{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<div align=\"center\">\n<font size=\"6\"> SIIM-ISIC Melanoma Classification  </font>  \n</div> \n\n\n<div align=\"center\">\n<font size=\"4\"> Identify melanoma in lesion images  </font>  \n</div> ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"---\n### Trabalho CSI707\n---\n\nKassio Rodrigues Ferreira","metadata":{}},{"cell_type":"code","source":"import pprint\nimport os\nimport re\nimport glob\nimport pathlib\nimport time\nimport math\nimport random\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nimport cv2\nimport seaborn as sns\n\nimport PIL\nfrom PIL import Image\n\nfrom sklearn.utils import class_weight\nfrom collections import Counter\n# ========================\n# Tensorflow::\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.models import Model,Sequential\nfrom tensorflow.keras.optimizers import Adam, SGD, RMSprop\nfrom tensorflow.keras.layers import Dropout, BatchNormalization\nfrom tensorflow.keras.layers import (\n    Input, Dense, Conv2D, Flatten, Activation, \n    MaxPooling2D, AveragePooling2D, ZeroPadding2D, GlobalAveragePooling2D, GlobalMaxPooling2D, add\n)\n\nfrom tensorflow.python.keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nfrom tensorflow.keras.utils import plot_model\n\nfrom tensorflow.keras.applications.vgg19 import VGG19\nfrom tensorflow.keras.applications.vgg19 import preprocess_input\nfrom tensorflow.keras.applications.resnet50 import ResNet50\nfrom tensorflow.keras.applications.resnet50 import preprocess_input\nfrom tensorflow.keras.applications.inception_v3 import InceptionV3\n\n\n","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:27.680801Z","iopub.execute_input":"2023-07-07T04:34:27.681217Z","iopub.status.idle":"2023-07-07T04:34:27.73366Z","shell.execute_reply.started":"2023-07-07T04:34:27.681177Z","shell.execute_reply":"2023-07-07T04:34:27.732794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# -------------------------------------\n# Define IMG PATHS\n# !ls ../input/skin-cancer9-classesisic\nBASE_PATH     = \"../input/siim-isic-melanoma-classification\"\nSAMPLES_PATH = \"../input/skin-cancer9-classesisic/Skin cancer ISIC The International Skin Imaging Collaboration\" \n\ntrain_path = os.path.join(SAMPLES_PATH, 'Train')\ntest_path  = os.path.join(SAMPLES_PATH, 'Test')\ntrain_dir = pathlib.Path(train_path)\ntest_dir  = pathlib.Path(test_path)","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:27.737639Z","iopub.execute_input":"2023-07-07T04:34:27.739668Z","iopub.status.idle":"2023-07-07T04:34:27.750526Z","shell.execute_reply.started":"2023-07-07T04:34:27.739629Z","shell.execute_reply":"2023-07-07T04:34:27.749617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_path)\nprint(test_path)","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:27.753498Z","iopub.execute_input":"2023-07-07T04:34:27.761393Z","iopub.status.idle":"2023-07-07T04:34:27.769999Z","shell.execute_reply.started":"2023-07-07T04:34:27.76135Z","shell.execute_reply":"2023-07-07T04:34:27.769184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n### Verificando as imgs:","metadata":{}},{"cell_type":"code","source":"img = Image.open(train_path+'/melanoma/ISIC_0000139.jpg')\nprint(f\" > img size : {img.size}\") \n\nimg_count_train = len(list(train_dir.glob('*/*.jpg')))\nimg_count_test  = len(list(test_dir.glob('*/*.jpg')))\nprint(' > train images : {}'.format(img_count_train))\nprint(' > test  images : {}'.format(img_count_test))","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:27.775012Z","iopub.execute_input":"2023-07-07T04:34:27.776158Z","iopub.status.idle":"2023-07-07T04:34:27.8558Z","shell.execute_reply.started":"2023-07-07T04:34:27.776123Z","shell.execute_reply":"2023-07-07T04:34:27.85493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n### Main configs","metadata":{}},{"cell_type":"code","source":"# --------------------------------------\n# Main configs:\nCFG = dict(\n    seed       = 99,\n    epochs     = 5,\n    batch_size = 96,\n    workers    = 2,\n    \n    optimizer  = 'adam',\n    label_smooth_fac  =  0.1,  # 0.01; 0.05; 0.1; 0.2;    \n    # img spec\n    img_size   = (128,128),\n    #img_size   = (128,128),\n    # Images augs\n    ROTATION          = 180.0,\n    ZOOM              =  10.0,\n    ZOOM_RANGE        =  [0.9,1.1],\n    HZOOM             =  10.0,\n    WZOOM             =  10.0,\n    HSHIFT            =  10.0,\n    WSHIFT            =  10.0,\n    SHEAR             =   5.0,\n    HFLIP             = True,\n    VFLIP             = True,  \n    \n    # Path to save a model\n    path_model        = '../working/',\n\n)\n\n\n# -----\nnp.random.seed(CFG['seed'])","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:27.856948Z","iopub.execute_input":"2023-07-07T04:34:27.862675Z","iopub.status.idle":"2023-07-07T04:34:27.878121Z","shell.execute_reply.started":"2023-07-07T04:34:27.862636Z","shell.execute_reply":"2023-07-07T04:34:27.877095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n## Carregando o Dataset\n\n","metadata":{}},{"cell_type":"code","source":"# -----------------\n# Classes ::\n# -----------------\nclass_names = [ class_name for class_name in os.listdir(train_dir) ]\nprint(f\" > classes:\\n {class_names} \\n ---\")","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:27.886746Z","iopub.execute_input":"2023-07-07T04:34:27.889071Z","iopub.status.idle":"2023-07-07T04:34:27.907264Z","shell.execute_reply.started":"2023-07-07T04:34:27.889019Z","shell.execute_reply":"2023-07-07T04:34:27.906283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Carregando amostras de treinamento, teste e validação\n","metadata":{}},{"cell_type":"code","source":"# ------------------------------------------------------\n# Carregando amostras de treinamento, teste e validação\n# ------------------------------------------------------\n\ntrain_ds = tf.keras.preprocessing.image_dataset_from_directory(\n    train_dir, validation_split=0.3, image_size=(224,224), subset=\"training\", seed=CFG['seed'] )\n\n# valid_ds = tf.keras.preprocessing.image_dataset_from_directory(\n#     train_dir, validation_split=0.3, image_size=(224,224), subset=\"validation\",seed=CFG['seed'] )\n\n# test_ds  = tf.keras.preprocessing.image_dataset_from_directory(\n#     test_dir, image_size=(CFG['img_size'][0] ,CFG['img_size'][1]), seed=CFG['seed'] )","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:27.908629Z","iopub.execute_input":"2023-07-07T04:34:27.908987Z","iopub.status.idle":"2023-07-07T04:34:28.213902Z","shell.execute_reply.started":"2023-07-07T04:34:27.90895Z","shell.execute_reply":"2023-07-07T04:34:28.21307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualizando amaostras","metadata":{}},{"cell_type":"code","source":"# --------------------------\n# Visualizando amaostras\n# --------------------------\nclasses = train_ds.class_names\nn_classes = len(classes)\n\n# plot amostras\nplt.figure(figsize=(23, 12))\nfor images, labels in train_ds.take(1):\n    for i in range(18):\n        ax = plt.subplot(3, 6, i + 1)\n        plt.imshow(images[i].numpy().astype(\"uint8\"))\n        plt.title(classes[labels[i]])\n        plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:28.219531Z","iopub.execute_input":"2023-07-07T04:34:28.221548Z","iopub.status.idle":"2023-07-07T04:34:35.289083Z","shell.execute_reply.started":"2023-07-07T04:34:28.221456Z","shell.execute_reply":"2023-07-07T04:34:35.288113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n## Pré-processamento das amostras\n\nEstratégias adotadas:\n\n - Diversificar as amostras com o ImageDataGenerator do Keras","metadata":{}},{"cell_type":"code","source":"# ------------------------------\n#  Define um data genenrator\n# Incluindo algumas opções p/ transoformações das amostras\n# ------------------------------\ntrain_datagen = ImageDataGenerator(\n    rescale                   = 1./255, \n    validation_split          = 0.3,\n    rotation_range            = CFG['ROTATION'],\n    zoom_range                = CFG['ZOOM_RANGE'],\n    horizontal_flip           = CFG['HFLIP'],\n    vertical_flip             = CFG['VFLIP'],\n    height_shift_range        = CFG['HSHIFT'],\n    width_shift_range         = CFG['WSHIFT'],\n    shear_range               = CFG['SHEAR'],\n    channel_shift_range       = 0.0,\n    brightness_range          = None,\n    fill_mode                 = 'nearest', \n)\n\n# -----------------------------------------------------------------------\n# Obtendo as amostras\nvalid_generator = ImageDataGenerator(rescale=1./255, validation_split=0.3)              # no aug for valid\ntest_generator  = ImageDataGenerator(rescale=1./255)                                    # no aug for test\n\n\n# Train data\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,\n    subset ='training',                  # to read train/valid from same directory \n    target_size = CFG['img_size'],\n    batch_size = CFG['batch_size'],\n    class_mode = 'categorical',\n)\n\n# Validation data\nvalid_generator = valid_generator.flow_from_directory(\n    train_dir,\n    subset = 'validation',               # to read train/valid from same directory \n    target_size = CFG['img_size'],\n    batch_size = CFG['batch_size'],\n    class_mode ='categorical'\n) \n\n# Test data\ntest_generator = test_generator.flow_from_directory(\n    test_dir,\n    target_size = CFG['img_size'],\n    batch_size = 1,                    # using 1 to easily manage mapping between test_gen & pred\n    class_mode = 'categorical'\n)","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:35.290909Z","iopub.execute_input":"2023-07-07T04:34:35.291256Z","iopub.status.idle":"2023-07-07T04:34:35.790328Z","shell.execute_reply.started":"2023-07-07T04:34:35.29122Z","shell.execute_reply":"2023-07-07T04:34:35.78939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(train_generator)","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:35.791582Z","iopub.execute_input":"2023-07-07T04:34:35.792319Z","iopub.status.idle":"2023-07-07T04:34:35.799191Z","shell.execute_reply.started":"2023-07-07T04:34:35.792278Z","shell.execute_reply":"2023-07-07T04:34:35.798249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n## Classe base p/ trabalhar com o dataset","metadata":{}},{"cell_type":"code","source":"#----------------------------------------------------------------\n# Encapsula os generators em uma única classe\n#----------------------------------------------------------------\nclass DataSet:\n    def __init__(self, train_gen, val_gen, test_gen, class_names):\n        self.train_gen   = train_gen\n        self.val_gen     = val_gen\n        self.test_gen    = test_gen\n        self.classes     = np.unique(train_gen.classes)\n        self.class_names = class_names\n        self.n_classes   = len(class_names)\n    \n    def get_class_weights(self):\n        \"\"\" Define pesos para as classes com sklear.utils.class_weight \"\"\"\n        # --------------------\n        # Obtendo os pesos\n        class_weights_list = class_weight.compute_class_weight(\n            class_weight ='balanced',\n            classes      = self.classes, \n            y            = self.train_gen.classes\n        ) \n\n        # -----------------\n        # definindo o formato padrão p/ entrada como parâmetro\n        # class_weight no Keras.model.fit()\n        class_weights = { self.classes[i] : w / 100 for i,w in enumerate(class_weights_list) }\n        \n        return class_weights\n        \n    # -------------------------\n    # Dataset info\n    #--------------------------\n    def plot_class_distrib(self):\n        \n        # Criar DataFrame\n        class_distrib = list(Counter(self.train_gen.classes).values())\n        df = pd.DataFrame({'Classes': range(1, len(class_distrib) + 1), 'Quantidade': class_distrib})\n\n        # Definir cores\n        cores = sns.color_palette('pastel')[0:len(class_distrib)]\n\n        # Plotar gráfico de barras\n        sns.barplot(data=df, x='Classes', y='Quantidade', palette=cores)\n\n        # Configurações do gráfico\n        plt.xlabel('Classes')\n        plt.ylabel('Quantidade')\n        plt.title('Distribuição das classes')\n\n        # Exibir o gráfico\n        plt.show()\n        \n        # Distrib detalhada\n        distrib_summary = pd.DataFrame(class_distrib, index=self.class_names, columns=['n_samples'])\n        display(distrib_summary)\n        ","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:35.800717Z","iopub.execute_input":"2023-07-07T04:34:35.802691Z","iopub.status.idle":"2023-07-07T04:34:35.831887Z","shell.execute_reply.started":"2023-07-07T04:34:35.802644Z","shell.execute_reply":"2023-07-07T04:34:35.831114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds = DataSet( train_gen = train_generator,\n              val_gen   = valid_generator,\n              test_gen  = test_generator,\n              class_names = class_names )\n\n","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:35.835499Z","iopub.execute_input":"2023-07-07T04:34:35.836087Z","iopub.status.idle":"2023-07-07T04:34:35.859181Z","shell.execute_reply.started":"2023-07-07T04:34:35.836051Z","shell.execute_reply":"2023-07-07T04:34:35.858386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds.plot_class_distrib()","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:35.862678Z","iopub.execute_input":"2023-07-07T04:34:35.864997Z","iopub.status.idle":"2023-07-07T04:34:36.154031Z","shell.execute_reply.started":"2023-07-07T04:34:35.864957Z","shell.execute_reply":"2023-07-07T04:34:36.153115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"----\n## Arquitetura da Rede:\n\n - Para facilitar a avaliação de diferentes arquiteturas foi definida a classe abstrata `NetBuilder` para manter uma interface única p/ construção dos modelos, podendo assim reaproveitar a estrutura original dos parâmetros de entrada, dataset e etc..","metadata":{}},{"cell_type":"code","source":"\"\"\" Utilitária p/ learning rate \"\"\"\nfrom tensorflow.keras.losses import CategoricalCrossentropy\nfrom tensorflow.keras.callbacks  import LearningRateScheduler\nfrom keras.callbacks import ReduceLROnPlateau\nfrom tensorflow.keras.regularizers import l2\n\n## --------------\n## Utils:\n\n## lr callback\nclass LrSchedCosine:\n    def __init__(self, epoch_begin, epoch_end, lr_begin):\n        self.epoch_begin = epoch_begin\n        self.epoch_end = epoch_end\n        self.lr_begin = lr_begin\n\n    def callback(self, epoch):\n        epoch += self.epoch_begin\n        epochs_warm = 2\n        if epoch <= epochs_warm:\n            lr = (epoch/epochs_warm) * self.lr_begin\n        else:\n            t = epoch - epochs_warm\n            T = self.epoch_end + epochs_warm\n            lr = .3 * ( 1 + np.cos( ( t  * np.pi ) / T ) ) * self.lr_begin\n        return lr","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:36.155474Z","iopub.execute_input":"2023-07-07T04:34:36.155821Z","iopub.status.idle":"2023-07-07T04:34:36.169417Z","shell.execute_reply.started":"2023-07-07T04:34:36.155784Z","shell.execute_reply":"2023-07-07T04:34:36.167667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from abc import ABC, abstractmethod\n\nclass NetBuilder(ABC):\n    \"\"\" Classe abstrata para construir modelos CNN.\"\"\"\n    \n    def __init__(self, dataset: DataSet, seed: int = 99, lr=1e-2):\n        self.ds = dataset\n        self.seed = seed\n        self.lr = lr\n    \n        \n    def init_seed(self):\n        random.seed(self.seed)\n        np.random.seed(self.seed)\n        tf.random.set_seed(self.seed)\n        tf.experimental.numpy.random.seed(self.seed)\n        os.environ['TF_CUDNN_DETERMINISTIC'] = '1'  # When running on the CuDNN backend, two further options must be set\n        os.environ['TF_DETERMINISTIC_OPS'] = '1'\n        os.environ[\"PYTHONHASHSEED\"] = str(self.seed)\n        print(f\"Random seed set as {self.seed}\")            \n\n    \n    @abstractmethod\n    def createModel(self):\n        pass\n    \n    @abstractmethod\n    def train(self, epochs: int = 5):\n        pass\n  ","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:36.193889Z","iopub.execute_input":"2023-07-07T04:34:36.194739Z","iopub.status.idle":"2023-07-07T04:34:36.204389Z","shell.execute_reply.started":"2023-07-07T04:34:36.194701Z","shell.execute_reply":"2023-07-07T04:34:36.203328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### DenseNet201 :\n\n- tf.keras.applications.DenseNet201\n- [https://keras.io/api/applications/densenet/](https://keras.io/api/applications/densenet/)\n","metadata":{}},{"cell_type":"markdown","source":"---\n### DenseNet201\n\n - A rede foi implementada seguindo os testes feitos com o dataset do DermaMNIST no notebook do colab.\n - O modelo base é o DenseNet201, carregado a partir do `keras.applications.DenseNet201`\n - Com a adição de 2 camadas densas antes da camada de saída com 512  e 64 neurônios, respectivamente, e dropout 0.5 e 0.0001\n \n - No treinamento foi adotado a taxa de aprendizado baseada no decaimento de cosseno ( implementação disponibilizda nos exemplos práticos do moodle.)\n ","metadata":{}},{"cell_type":"code","source":"from keras.applications.densenet import DenseNet201\n\nclass CustomNET(NetBuilder):\n    def __init__(self, dataset, seed: int = 99, lr=1e-2):\n        super().__init__(dataset=dataset, seed=seed, lr=lr)\n        super().init_seed()\n        self.model = self.createModel()\n    \n    \n    def createModel(self):        \n\n        model = tf.keras.Sequential([\n            tf.keras.applications.DenseNet201(\n              input_shape=(CFG['img_size'][0], CFG['img_size'][0], 3),\n              weights='imagenet',\n              include_top=False\n          ),\n\n          # ------------------------------------------------------------------------------\n\n          GlobalAveragePooling2D(),\n\n          Dense(512, activation = 'relu'),\n          Dropout(0.5),\n          BatchNormalization(),\n\n          Dense(64, activation='relu'),\n          Dropout(0.0001),\n          BatchNormalization(),\n\n\n\n          Dense(self.ds.n_classes, activation='softmax') # num classes = 9\n\n        ])\n\n        # teste ::\n        optimizer = Adam(learning_rate=self.lr, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=True)\n\n        model.compile(\n          optimizer=optimizer,\n          loss='categorical_crossentropy',\n          #loss = 'binary_crossentropy',\n          metrics=['acc']\n        )\n\n\n        return model\n\n    \n    \n    def train(self, epochs: int = 5):\n        # -------------------------------------\n        # p/ salvar os pesos\n        tf.config.run_functions_eagerly(True) # otherwise error\n\n        # https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/ModelCheckpoint\n        cb_early_stopper = EarlyStopping(monitor = 'val_loss', patience = 40)\n        cb_checkpointer  = ModelCheckpoint(#filepath=path_model,\n                                           #filepath=CFG['path_model']+'ResNet50.hdf5'\n                                           filepath = CFG['path_model']+'ResNet50-{epoch:02d}-{val_loss:.2f}.hdf5',\n                                           monitor  = 'val_loss', \n                                           verbose  = 1, \n                                           save_best_only=True, \n                                           mode='min'\n                                          )        \n        \n        lr_schedule_cosine =  LrSchedCosine(0, epochs, self.lr)\n        lr_scheduler = LearningRateScheduler( lr_schedule_cosine.callback )\n        #lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=5, verbose=1)\n        callbacks_list = [ lr_scheduler ]\n        #callbacks_list = [ lr_scheduler, cb_early_stopper ]\n        \n        history = self.model.fit(\n            self.ds.train_gen,\n            epochs=epochs,\n            batch_size=CFG['batch_size'],\n            workers=CFG['workers'],\n            validation_data=self.ds.val_gen,\n            callbacks = callbacks_list,\n        )\n\n        return history\n","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:36.221246Z","iopub.execute_input":"2023-07-07T04:34:36.221623Z","iopub.status.idle":"2023-07-07T04:34:36.249094Z","shell.execute_reply.started":"2023-07-07T04:34:36.221585Z","shell.execute_reply":"2023-07-07T04:34:36.246451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n### Treinando a rede","metadata":{}},{"cell_type":"code","source":"net = CustomNET(dataset=ds, seed=CFG['seed'])","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:36.252956Z","iopub.execute_input":"2023-07-07T04:34:36.253289Z","iopub.status.idle":"2023-07-07T04:34:42.393028Z","shell.execute_reply.started":"2023-07-07T04:34:36.253261Z","shell.execute_reply":"2023-07-07T04:34:42.392119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#epochs = CFG['epochs']\nepochs = 60\nhistory = net.train(epochs=epochs)\nmodel = net.model","metadata":{"execution":{"iopub.status.busy":"2023-07-07T04:34:42.394282Z","iopub.execute_input":"2023-07-07T04:34:42.394644Z","iopub.status.idle":"2023-07-07T05:27:13.621522Z","shell.execute_reply.started":"2023-07-07T04:34:42.394605Z","shell.execute_reply":"2023-07-07T05:27:13.617448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n## Avaliando o treinamento:","metadata":{}},{"cell_type":"markdown","source":"### Acurácia:","metadata":{}},{"cell_type":"code","source":"from sklearn import metrics\ndir(ds.train_gen.samples)\ny_pred = model.predict( ds.test_gen )\ny_pred_dec = np.argmax(y_pred, axis=1)\ny_true = ds.test_gen.classes\nacc_score = metrics.accuracy_score(y_true, y_pred_dec)\n\nprint(f\"Accuracy: {acc_score}\")","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:27:13.623131Z","iopub.execute_input":"2023-07-07T05:27:13.623505Z","iopub.status.idle":"2023-07-07T05:27:41.450728Z","shell.execute_reply.started":"2023-07-07T05:27:13.623454Z","shell.execute_reply":"2023-07-07T05:27:41.449754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Performance do treinamento","metadata":{}},{"cell_type":"code","source":"loss_h = pd.DataFrame(history.history)\n# display(loss_h)\n\n\nplt.clf()\nloss_h.plot(figsize=(8,5))\nplt.grid(True)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:27:41.45201Z","iopub.execute_input":"2023-07-07T05:27:41.452392Z","iopub.status.idle":"2023-07-07T05:27:41.653346Z","shell.execute_reply.started":"2023-07-07T05:27:41.452358Z","shell.execute_reply":"2023-07-07T05:27:41.65238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss_h = pd.DataFrame(history.history)\n# display(loss_h)\n__loss = loss_h\n__loss = __loss.drop('val_loss', axis=1)\n\n#display(__loss)\n\nplt.clf()\n__loss.plot(figsize=(8,5))\nplt.grid(True)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:27:41.656853Z","iopub.execute_input":"2023-07-07T05:27:41.657906Z","iopub.status.idle":"2023-07-07T05:27:41.861555Z","shell.execute_reply.started":"2023-07-07T05:27:41.657863Z","shell.execute_reply":"2023-07-07T05:27:41.860656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Matriz de confusão","metadata":{}},{"cell_type":"code","source":"cf_matrix = metrics.confusion_matrix(y_true, y_pred_dec)\n\nfig, ax = plt.subplots(figsize=(10, 8))\nax = sns.heatmap(cf_matrix, annot=True, fmt=\"d\", cmap='Blues')\n\nax.set_title('Matriz de Confusão - Softmax\\n\\n');\nax.set_xlabel('\\nValores Preditos')\nax.set_ylabel('Valores Reais');\n\n## Ticket labels - List must be in alphabetical order\nax.xaxis.set_ticklabels([ i for i in range(len(ds.classes)) ], rotation=30, horizontalalignment='right', fontsize=8)\nax.yaxis.set_ticklabels([ i for i in range(len(ds.classes)) ], rotation=30, horizontalalignment='right', fontsize=8)\n\n## Display the visualization of the Confusion Matrix.\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:27:41.863149Z","iopub.execute_input":"2023-07-07T05:27:41.863697Z","iopub.status.idle":"2023-07-07T05:27:42.487813Z","shell.execute_reply.started":"2023-07-07T05:27:41.863652Z","shell.execute_reply":"2023-07-07T05:27:42.486914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Separação das classes no plano","metadata":{}},{"cell_type":"code","source":"ds.train_gen.n","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:27:42.489265Z","iopub.execute_input":"2023-07-07T05:27:42.489867Z","iopub.status.idle":"2023-07-07T05:27:42.496092Z","shell.execute_reply.started":"2023-07-07T05:27:42.489826Z","shell.execute_reply":"2023-07-07T05:27:42.495115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.manifold import TSNE\n\nlast_layer = model.layers[-1]\nlayer_name = last_layer.name\nm1 = Model( inputs = model.input, outputs = model.get_layer( layer_name ).output )\nx2 = m1.predict( ds.train_gen )\nfeatures = x2.reshape( np.shape( x2 )[0], np.prod( np.shape( x2 )[1:4] ) )\n\n\nfeatures = features[0:ds.train_gen.n,:]\ntsne = TSNE( n_components=2 );\nfeatures_tsne = tsne.fit_transform( features );  #esta parte demora\n#save(my_folder + file + '-tsne.npy', features_tsne)\n#features_tsne = load(my_folder + file + '-tsne.npy')\n\nplt.rcParams[\"figure.figsize\"] = ( 8, 8 )\nplt.grid( True )\nplt.scatter( features_tsne[0:len(features),0], features_tsne[0:len(features),1], c=ds.train_gen.classes)\nplt.xlabel( \"$f_1$\", fontsize = 20 )\nplt.ylabel( \"$f_2$\", fontsize = 20 )","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:27:42.497394Z","iopub.execute_input":"2023-07-07T05:27:42.497792Z","iopub.status.idle":"2023-07-07T05:28:20.822623Z","shell.execute_reply.started":"2023-07-07T05:27:42.497756Z","shell.execute_reply":"2023-07-07T05:28:20.821747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n### Salvando o modelo","metadata":{}},{"cell_type":"code","source":"#model.save_weights('Dense201_ok.h5')","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:38:36.310571Z","iopub.execute_input":"2023-07-07T05:38:36.31093Z","iopub.status.idle":"2023-07-07T05:38:36.99834Z","shell.execute_reply.started":"2023-07-07T05:38:36.310895Z","shell.execute_reply":"2023-07-07T05:38:36.997356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n#### Teste: Carregando o modelo da rede com os pesos","metadata":{}},{"cell_type":"code","source":"# net2 = CustomNET(dataset=ds, seed=CFG['seed'])\n# net2","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:40:02.228927Z","iopub.execute_input":"2023-07-07T05:40:02.229326Z","iopub.status.idle":"2023-07-07T05:40:08.472922Z","shell.execute_reply.started":"2023-07-07T05:40:02.229291Z","shell.execute_reply":"2023-07-07T05:40:08.471932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model_loaded = net2.model\n# model_loaded","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:40:23.664746Z","iopub.execute_input":"2023-07-07T05:40:23.665122Z","iopub.status.idle":"2023-07-07T05:40:23.670901Z","shell.execute_reply.started":"2023-07-07T05:40:23.665081Z","shell.execute_reply":"2023-07-07T05:40:23.669979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model_loaded.load_weights('Dense201_ok.h5')","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:40:48.895891Z","iopub.execute_input":"2023-07-07T05:40:48.896296Z","iopub.status.idle":"2023-07-07T05:40:49.557173Z","shell.execute_reply.started":"2023-07-07T05:40:48.89626Z","shell.execute_reply":"2023-07-07T05:40:49.556182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from sklearn import metrics\n# y_pred = model_loaded.predict( ds.test_gen )\n# y_pred_dec = np.argmax(y_pred, axis=1)\n# y_true = ds.test_gen.classes\n# acc_score = metrics.accuracy_score(y_true, y_pred_dec)\n\n# print(f\"Accuracy: {acc_score}\")","metadata":{"execution":{"iopub.status.busy":"2023-07-07T05:44:17.281534Z","iopub.execute_input":"2023-07-07T05:44:17.281933Z","iopub.status.idle":"2023-07-07T05:44:42.619125Z","shell.execute_reply.started":"2023-07-07T05:44:17.28188Z","shell.execute_reply":"2023-07-07T05:44:42.61702Z"},"trusted":true},"execution_count":null,"outputs":[]}]}