<jupyter_start><jupyter_text>Pré: Conexão com Google Drive<jupyter_code>from google.colab import drive
drive.mount('/content/drive')<jupyter_output>Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).<jupyter_text>Etapa 1: Instalação das dependências<jupyter_code>!pip install tensorflow-gpu==2.1.0
!pip install tqdm
!pip install kaggle
!pip install keras-rectified-adam
#!pip install tensorflow-addons
!pip install tfa-nightly<jupyter_output>Collecting tensorflow-gpu==2.1.0
  Using cached https://files.pythonhosted.org/packages/0a/93/c7bca39b23aae45cd2e85ad3871c81eccc63b9c5276e926511e2e5b0879d/tensorflow_gpu-2.1.0-cp36-cp36m-manylinux2010_x86_64.whl
Requirement already satisfied: keras-applications>=1.0.8 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.1.0) (1.0.8)
Requirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.1.0) (1.11.2)
Requirement already satisfied: six>=1.12.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.1.0) (1.12.0)
Requirement already satisfied: keras-preprocessing>=1.1.0 in /usr/local/lib/python3.6/dist-packages (from tensorflow-gpu==2.1.0) (1.1.0)
Collecting tensorboard<2.2.0,>=2.1.0
[?25l  Downloading https://files.pythonhosted.org/packages/40/23/53ffe290341cd0855d595b0a2e7485932f473798af173bbe3a584b99bb06/tensorboard-2.1.0-py3-none-any.whl (3.8MB)
[K     |████████████████████████████████| 3.8MB 2.8MB/s 
[[...]<jupyter_text>Importação das bibliotecas<jupyter_code>import zipfile
import os
import numpy as np
import tensorflow as tf
import tensorflow_addons as tfa

import matplotlib.pyplot as plt
import pandas as pd
import sys
import itertools
from keras_radam import RAdam
import shutil

from tqdm import tqdm_notebook
from tensorflow.keras.preprocessing.image import ImageDataGenerator

%matplotlib inline
tf.__version__<jupyter_output>Using TensorFlow backend.<jupyter_text>Otimizações tensorflow<jupyter_code>#from tensorflow.keras.mixed_precision import experimental as mixed_precision
#policy = mixed_precision.Policy('mixed_float16')
#mixed_precision.set_policy(policy)
tf.config.optimizer.set_jit(True)<jupyter_output><empty_output><jupyter_text>Fazendo o download da base de dados de imagens<jupyter_code>ISIC2018_Task3_Training_Input = './ISIC2018_Task3_Training_Input'
ISIC2018_Task3_Test_Input = './ISIC2018_Task3_Test_Input'
ISIC2018_Task3_Training_GroundTruth = './ISIC2018_Task3_Training_GroundTruth'
ground_truth_file = './ground_truth'
%%time
if (os.path.isdir(ISIC2018_Task3_Training_Input)==False):
  !wget --no-check-certificate \
      https://challenge.kitware.com/api/v1/item/5ac20fc456357d4ff856e139/download \
      -O ./skin_cancer_train.zip
%%time
#if (os.path.isdir('./ISIC_2018_Valid_Input')==False):
#  !wget --no-check-certificate \
#      https://challenge.kitware.com/api/v1/item/5b1c1c7256357d41064da302/download \
#      -O ./skin_cancer_valid.zip
#%%time
#if (os.path.isdir(ISIC2018_Task3_Test_Input)==False):
#  !wget --no-check-certificate \
#      https://challenge.kitware.com/api/v1/item/5b1c200656357d41064da305/download \
#      -O ./skin_cancer_test.zip
%%time
if (os.path.isdir(ground_truth_file)==False):
  !wget --no-check-certificate \
      https://challenge.kitware.com/api/v1/item/5ac20eeb56357d4ff856e136/download \
      -O ./ground_truth.zip<jupyter_output>--2020-03-02 23:13:12--  https://challenge.kitware.com/api/v1/item/5ac20eeb56357d4ff856e136/download
Resolving challenge.kitware.com (challenge.kitware.com)... 172.16.17.32
Connecting to challenge.kitware.com (challenge.kitware.com)|172.16.17.32|:443... connected.
HTTP request sent, awaiting response... 303 See Other
Location: https://s3.amazonaws.com/isic-challenge-data/f0/43/f043e9c1a29c45eca0d6109df5d5baed?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=3600&X-Amz-Credential=AKIAIPOKLGIV7XKXF5FA%2F20200302%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Date=20200302T231312Z&X-Amz-Signature=4a305ad98f829e5e47317cf89dfcd22150e0d144677e4bcde23368be1050b836 [following]
--2020-03-02 23:13:12--  https://s3.amazonaws.com/isic-challenge-data/f0/43/f043e9c1a29c45eca0d6109df5d5baed?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=3600&X-Amz-Credential=AKIAIPOKLGIV7XKXF5FA%2F20200302%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Date=20200302T231312Z&X-Amz-Sig[...]<jupyter_text>Etapa 2: Pré-processamento  Configurando os caminhos (paths)<jupyter_code>train_dir = "./train"
if not os.path.exists(train_dir): 
  os.mkdir(train_dir)

valid_dir = "./valid"
if not os.path.exists(valid_dir): 
  os.mkdir(valid_dir)

test_dir = "./test"
if not os.path.exists(test_dir): 
  os.mkdir(test_dir)


download_path = './'
derm_ai_path_V1 = '/content/drive/My Drive/Colab Notebooks/Dermatologist_AI'
derm_ai_path = '/content/drive/My Drive/Colab Notebooks/Dermatologist_AI/ISIC_2018/MEL_NEV'
#ground_truth_file = os.path.join('ground_truth.csv')
def dcp(download_path, path, file):
  if (os.path.isdir(path)==False):
    dataset_path = os.path.join(download_path,file)
    zip_object = zipfile.ZipFile(file=dataset_path, mode="r")
    zip_object.extractall("./")
    zip_object.close()
    !rm file<jupyter_output><empty_output><jupyter_text>Descompactando a base de dados de Treinamento<jupyter_code>%%time
dcp(download_path, ISIC2018_Task3_Training_Input, 'skin_cancer_train.zip')
#!rm ./skin_cancer_train.zip
%%time
#dcp(download_path, './ISIC2018_Task3_Validation_Input', 'skin_cancer_valid.zip')
#!rm ./skin_cancer_valid.zip<jupyter_output>CPU times: user 2 µs, sys: 1 µs, total: 3 µs
Wall time: 5.48 µs<jupyter_text>Descompactando a base de dados de Testes<jupyter_code>#%%time
#dcp(download_path, ISIC2018_Task3_Test_Input, 'skin_cancer_test.zip')
#!rm ./skin_cancer_test.zip
%%time
dcp(download_path, ISIC2018_Task3_Training_GroundTruth, 'ground_truth.zip')
#!rm ./ground_truth.zip
# Read in the data
ground_truth = pd.read_csv('/content/ISIC2018_Task3_Training_GroundTruth/ISIC2018_Task3_Training_GroundTruth.csv')

# Display some information in the dataset
ground_truth.head()
# Set y as the labels
y = []
for row in ground_truth.iterrows():
    innerlist = []
    newlist = row[1].index[row[1].values[1:].argmax() + 1]
    y.append(newlist)


#add a name to the label series
yd = pd.Series(y) 
yd.name = 'cclass'

from sklearn.model_selection import train_test_split
df_train, df_val = train_test_split(ground_truth, test_size=0.2, random_state=41, stratify=yd)

# Get a list of images in each of the two folders
folder = os.listdir(ISIC2018_Task3_Training_Input)

# Get a list of train and val images
#all_list = list(ground_truth['image'])
#
train_list = list(df_train['image'])
val_list = list(df_val['image'])
#os.mkdir(train_dir)
#os.mkdir(valid_dir)
#create sub directory for the classes
for col in ground_truth.columns:
    if not (col == 'image' or  col == 'UNK'):
        dir_path = os.path.join(train_dir, col)
        if not os.path.exists(dir_path):
          os.mkdir(dir_path)
        dir_path = os.path.join(valid_dir, col)
        if not os.path.exists(dir_path):
          os.mkdir(dir_path)
# Transfer the training images
for row in df_train.iterrows():
    image = row[1].image
    # The argmax error was occuring because the first column (image) is a string.
    # By using row[1].values[1:] we skip the first column.  This means we need 
    # add 1 to get the correct row[1].index.
    label = row[1].index[row[1].values[1:].argmax() + 1]
    fname = image + '.jpg'

    if fname in folder:
        # source path to image
        src = os.path.join(ISIC2018_Task3_Training_Input, fname)
        # destination path to image
        dst = os.path.join(train_dir, label, fname)
        # copy the image from the source to the destination
        shutil.copyfile(src, dst)
# Transfer the valid images
for row in df_val.iterrows():
    image = row[1].image
    # The argmax error was occuring because the first column (image) is a string.
    # By using row[1].values[1:] we skip the first column.  This means we need 
    # add 1 to get the correct row[1].index.
    label = row[1].index[row[1].values[1:].argmax() + 1]
    fname = image + '.jpg'

    if fname in folder:
        # source path to image
        src = os.path.join(ISIC2018_Task3_Training_Input, fname)
        # destination path to image
        dst = os.path.join(valid_dir, label, fname)
        # copy the image from the source to the destination
        shutil.copyfile(src, dst)
!rm -rf '/content/train/AKIEC'
!rm -rf '/content/train/BCC'
!rm -rf '/content/train/BKL'
!rm -rf '/content/train/DF'
!rm -rf '/content/train/VASC'

!rm -rf '/content/valid/AKIEC'
!rm -rf '/content/valid/BCC'
!rm -rf '/content/valid/BKL'
!rm -rf '/content/valid/DF'
!rm -rf '/content/valid/VASC'
#axis{0 or ‘index’, 1 or ‘columns’}
ground_truth.drop(axis=1, columns=['AKIEC','BCC','BKL','DF','VASC'], inplace=True)
ground_truth.head()
# training examples
total = 0
for col in ground_truth.columns:
    if not (col == 'image' or  col == 'UNK'):
        npath = os.path.join(train_dir, col)
        print(col,len(os.listdir(npath)))
        total = total+len(os.listdir(npath))
print('total = ',total)
# validation examples
total = 0
for col in ground_truth.columns:
    if not (col == 'image' or  col == 'UNK'):
        npath = os.path.join(valid_dir, col)
        print(col,len(os.listdir(npath)))
        total = total+len(os.listdir(npath))
print('total = ',total)
import os, random
mellen = len(os.listdir('./valid/MEL'))
nvlen = len(os.listdir('./valid/NV'))
for i in range(nvlen - mellen):
    file = random.choice(os.listdir("./valid/NV"))
    dst = os.path.join(valid_dir,'NV', file)
    os.remove(dst)
# validation examples
total = 0
for col in ground_truth.columns:
    if not (col == 'image' or  col == 'UNK'):
        npath = os.path.join(valid_dir, col)
        print(col,len(os.listdir(npath)))
        total = total+len(os.listdir(npath))
print('total = ',total)        
val_len = total<jupyter_output>MEL 223
NV 223
total =  446<jupyter_text>AKBCCBKLDFMEL MelanomaNVSCCVASC  Criando geradores de dados (Data Generators)Redimensionando as imagens    Grandes arquiteturas treinadas suportam somente alguns tamanhos pré-definidos.Por exemplo: InceptionResNetV2 (que estamos usando) suporta: (299x299).<jupyter_code># Data Augmentation (https://keras.io/preprocessing/image/)
data_gen_train = ImageDataGenerator(#validation_split=0.2,
                                    rescale=1/255., 
                                    horizontal_flip= True, 
                                    vertical_flip = True, 
                                    height_shift_range=0.10, 
                                    width_shift_range=0.10,
                                    rotation_range=180,
                                    shear_range=0.01,
                                    zoom_range=[0.95, 1.25],
                                    fill_mode='constant',
                                    #data_format='channels_last',
                                    #brightness_range=[0.9, 1.1]
                                    )

data_gen_valid = ImageDataGenerator(rescale=1/255., 
                                   fill_mode="constant"
)

#data_gen_test = ImageDataGenerator(rescale=1/255., 
#                                   fill_mode="constant"
#)
#!mkdir ./test
#!mkdir ./test/test
#!mv ./ISIC2018_Task3_Test_Input/* ./test/test
train_generator = data_gen_train.flow_from_directory(train_dir, target_size=(299,299), batch_size=32, class_mode="categorical")
valid_generator = data_gen_valid.flow_from_directory(valid_dir, target_size=(299,299), batch_size=32, class_mode="categorical")
#test_generator  = data_gen_test.flow_from_directory(test_dir, target_size=(299,299), batch_size=32, shuffle=False, class_mode=None)<jupyter_output>Found 6254 images belonging to 2 classes.
Found 446 images belonging to 2 classes.<jupyter_text>Exibição de 3 imagens carregadas<jupyter_code>x,y = train_generator.next()
for i in range(0,3):
    image = x[i]
    label = y[i]
    print (label)
    plt.imshow(image)
    plt.show()<jupyter_output>[0. 1.]<jupyter_text>Balanceando treinamento<jupyter_code>from sklearn.utils import class_weight
import numpy as np

class_weights = class_weight.compute_class_weight(
           'balanced',
            np.unique(train_generator.classes), 
            train_generator.classes)<jupyter_output><empty_output><jupyter_text>Etapa 3: Construindo o modelo  Carregando o modelo pré-treinado (InceptionResNetV2)<jupyter_code>img_shape = (299, 299, 3)
base_model_InceptionResNetV2 = tf.keras.applications.InceptionResNetV2(input_shape = img_shape, 
                                               include_top = False,
                                               weights = "imagenet")

#congelando a base
base_model_InceptionResNetV2.trainable = False
#base_model_InceptionResNetV2.trainable = False<jupyter_output><empty_output><jupyter_text>Definindo o cabeçalho personalizado da rede neural  Personalização e união dos modelos<jupyter_code>Flatten_layer = tf.keras.layers.Flatten()(base_model_InceptionResNetV2.output)
Flatten_layer = tf.keras.layers.Dense(1024, activation="relu")(Flatten_layer)
Flatten_layer = tf.keras.layers.Dense(512, activation="relu")(Flatten_layer)
prediction_layer = tf.keras.layers.Dense(units = 2, activation = "softmax")(Flatten_layer)

#model
model = tf.keras.models.Model(inputs = base_model_InceptionResNetV2.input, outputs = prediction_layer)

#compilador
model.compile(optimizer='adam', loss="categorical_crossentropy", metrics=[tf.keras.metrics.CategoricalAccuracy()])

model.summary()<jupyter_output>Model: "model_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_2 (InputLayer)            [(None, 299, 299, 3) 0                                            
__________________________________________________________________________________________________
conv2d_203 (Conv2D)             (None, 149, 149, 32) 864         input_2[0][0]                    
__________________________________________________________________________________________________
batch_normalization_203 (BatchN (None, 149, 149, 32) 96          conv2d_203[0][0]                 
__________________________________________________________________________________________________
activation_203 (Activation)     (None, 149, 149, 32) 0           batch_normalization_203[0][[...]<jupyter_text>Treinando o modelo<jupyter_code>%%time
model.fit(train_generator, epochs=2, validation_data=valid_generator, class_weight=class_weights)<jupyter_output>WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
Train for 196 steps, validate for 14 steps
Epoch 1/2
196/196 [==============================] - 209s 1s/step - loss: 2.6878 - categorical_accuracy: 0.8110 - val_loss: 3.5607 - val_categorical_accuracy: 0.5000
Epoch 2/2
196/196 [==============================] - 186s 949ms/step - loss: 0.3275 - categorical_accuracy: 0.8679 - val_loss: 1.8312 - val_categorical_accuracy: 0.5135
CPU times: user 6min 48s, sys: 10.6 s, total: 6min 59s
Wall time: 6min 36s<jupyter_text>Avaliação do modelo de transferência de aprendizagem<jupyter_code>valid_loss, valid_acc = model.evaluate(valid_generator)
valid_acc<jupyter_output>WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
14/14 [==============================] - 5s 339ms/step - loss: 1.8312 - categorical_accuracy: 0.5135<jupyter_text>Etapa 4: Fine tuning  Descongelando algumas camadas do topo do modelo base<jupyter_code>print("base_model_Xception: {} layers".format(len(base_model_InceptionResNetV2.layers)))
#print("base_model_InceptionResNetV2: {} layers".format(len(base_model_InceptionResNetV2.layers)))
#print("base_model_InceptionV3: {} layers".format(len(base_model_InceptionV3.layers)))<jupyter_output>base_model_Xception: 780 layers<jupyter_text>Descomentar trecho abaixo para manter camadas congeladas. O número informado no parâmetro `fine_tuning_at` define o número das primeiras camadas que ficarão congeladas. Supondo que a rede tenha 780 camadas e seja informado o valor 500, até a camada 500 a rede ficará congelada.<jupyter_code>#descongelando a base

base_model_InceptionResNetV2.trainable = True
#fine_tuning_at = 100
#for layer in base_model_InceptionResNetV2.layers[:fine_tuning_at]:
#  layer.trainable = False


#base_model_InceptionV3.trainable = False


#base_model_InceptionResNetV2.trainable = False
#fine_tuning_at = 200
#for layer in base_model_InceptionResNetV2.layers[:fine_tuning_at]:
#  layer.trainable = False<jupyter_output><empty_output><jupyter_text>Compilando o modelo para fine tuning<jupyter_code>#compilador
model.compile(optimizer=tf.keras.optimizers.Adadelta(), loss=tf.keras.losses.CategoricalCrossentropy(), metrics=[tf.keras.metrics.Recall(),tf.keras.metrics.CategoricalAccuracy()])<jupyter_output><empty_output><jupyter_text>Fine tuning<jupyter_code>%%time

checkpoint_filepath = os.path.join(derm_ai_path, 'MEL_NEV.best.weights.hdf5')

my_checkpointer = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_filepath,
                                                 save_best_only=True,
                                                 monitor='val_recall_5',
                                                 mode='max',
                                                 verbose=1)

history = model.fit(train_generator, epochs=5, validation_data=valid_generator, callbacks=[my_checkpointer], class_weight=class_weights) #10  5 5 5 5 (80-20)<jupyter_output>WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
Train for 196 steps, validate for 14 steps
Epoch 1/5
195/196 [============================>.] - ETA: 0s - loss: 0.2475 - recall_5: 0.8978 - categorical_accuracy: 0.8978
Epoch 00001: val_recall_5 improved from -inf to 0.75336, saving model to /content/drive/My Drive/Colab Notebooks/Dermatologist_AI/ISIC_2018/MEL_NEV/MEL_NEV.best.weights.hdf5
196/196 [==============================] - 178s 908ms/step - loss: 0.2468 - recall_5: 0.8983 - categorical_accuracy: 0.8983 - val_loss: 0.5363 - val_recall_5: 0.7534 - val_categorical_accuracy: 0.7534
Epoch 2/5
195/196 [============================>.] - ETA: 0s - loss: 0.2437 - recall_5: 0.8949 - categorical_accuracy: 0.8949
Epoch 00002: val_recall_5 improved from 0.75336 to 0.77578, saving model to /content/drive/My Drive/Colab Notebooks/Dermatologist_AI/ISIC_2018/MEL_NEV/MEL_NEV.best.we[...]<jupyter_text>Avaliação do modelo com fine tuning<jupyter_code>valid_loss, valid_recall, valid_categorical  = model.evaluate(valid_generator)
valid_recall
# Retrieve a list of accuracy results on training and test data
# sets for each training epoch
acc = history.history['recall_5']
val_acc = history.history['val_recall_5']

# Retrieve a list of list results on training and test data
# sets for each training epoch
loss = history.history['loss']
val_loss = history.history['val_loss']

# Get number of epochs
epochs = range(len(acc))

# Plot training and validation accuracy per epoch
plt.plot(epochs, acc, label = "training")
plt.plot(epochs, val_acc, label = "validation")
plt.legend(loc="upper left")
plt.title('Training and validation accuracy')

plt.figure()

# Plot training and validation loss per epoch
plt.plot(epochs, loss, label = "training")
plt.plot(epochs, val_loss, label = "validation")
plt.legend(loc="upper right")
plt.title('Training and validation loss')<jupyter_output><empty_output><jupyter_text>Carregar modelo após Fine Tuning com os melhores pesos<jupyter_code>#checkpoint_filepath = os.path.join(derm_ai_path, 'xception_NV_MEL_val_loss.best.weights.hdf5')
#checkpoint_filepath = os.path.join(derm_ai_path, 'xception_NV_MEL_precision_at_recall_0.90.best.weights.hdf5')
checkpoint_filepath = os.path.join(derm_ai_path, 'MEL_NEV.best.weights.hdf5')
model.load_weights(checkpoint_filepath)

# Show the model architecture
#model.summary()<jupyter_output><empty_output><jupyter_text>Matriz de Validação<jupyter_code># Create a confusion matrix of the test images
val_labels = valid_generator.classes
# Make predictions
val_predictions = model.predict(valid_generator)
from sklearn.metrics import confusion_matrix

# Declare a function for plotting the confusion matrix
def plot_confusion_matrix(cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()

cm = confusion_matrix(val_labels, val_predictions.argmax(axis=1))

cm_plot_labels = ['ML','NV']

plot_confusion_matrix(cm, cm_plot_labels)<jupyter_output>Confusion matrix, without normalization
[[ 98 125]
 [ 88 135]]<jupyter_text>Identificar classe predita<jupyter_code>def predClasses(pred, train_generator):
  predicted_class_indices=np.argmax(pred,axis=1)

  labels = (train_generator.class_indices)
  labels = dict((v,k) for k,v in labels.items())
  predictions = [labels[k] for k in predicted_class_indices]
  return predicted_class_indices, labels, predictions

predicted_class_indices, labels, predictions = predClasses(val_predictions, train_generator)
labels
predictions[0]
predicted_class_indices[0]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12734864300626306, 'fraction_numerical': 0.04886065828632346, 'mean_word_length': 4.228518346493265, 'pattern_counts': {'":': 0, '<': 80, '<?xml version=': 0, '>': 87, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 42, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '23', 'dir': 'jupyter-structured-clean-dedup', 'id': '603695', 'license': 'MIT', 'n_tokens_mistral': 8556, 'n_tokens_neox': 7719, 'n_words': 1494, 'path': 'ISIC 2018/MEL_NEV/01_Train01_ISIC_2018_InceptionResNetV2 - NV-ML.ipynb', 'repo_name': 'cccadet/dermatologist-ai', 'size': '22517'}