{"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":"code","source":"import time, os, sys\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport tensorflow as tf\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras import layers, metrics, losses, callbacks, regularizers, datasets, models\nfrom tensorflow import keras\nfrom tensorflow.python.client import device_lib\nfrom sklearn.model_selection import train_test_split\nfrom kaggle_datasets import KaggleDatasets\n\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.metrics import classification_report, confusion_matrix\n\nplt.rc('figure', autolayout=True)\nplt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)\nplt.rc('image', cmap='magma')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-05T21:28:06.23654Z","iopub.execute_input":"2023-05-05T21:28:06.236797Z","iopub.status.idle":"2023-05-05T21:28:12.497474Z","shell.execute_reply.started":"2023-05-05T21:28:06.236767Z","shell.execute_reply":"2023-05-05T21:28:12.496733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Baixando conjunto de dados\n!unzip -q -n ../input/galaxy-zoo-the-galaxy-challenge/images_training_rev1.zip -d ../temp/\n!unzip -q -n ../input/galaxy-zoo-the-galaxy-challenge/images_test_rev1.zip -d ../temp/     \nlabels_pd = pd.read_csv('../input/galaxy-zoo-the-galaxy-challenge/training_solutions_rev1.zip',compression='zip')\n#labels_pd_test = pd.read_csv('/kaggle/input/galaxy-zoo-the-galaxy-challenge/images_test_rev1.zip',compression='zip')\n#labels_pd_train = pd.read_csv('/kaggle/input/galaxy-zoo-the-galaxy-challenge/images_training_rev1.zip',compression='zip')\n\nfor dirname, _, filenames in os.walk('../input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n        \nprint(\"Dataset loading done!\")","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:12.501405Z","iopub.execute_input":"2023-05-05T21:28:12.501607Z","iopub.status.idle":"2023-05-05T21:28:17.484855Z","shell.execute_reply.started":"2023-05-05T21:28:12.501581Z","shell.execute_reply":"2023-05-05T21:28:17.483953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Esta função retorna as primeiras n linhas para o objeto com base na posição... \n# ...É útil para testar rapidamente se o seu objeto contém o tipo certo de dados.\nlabels_pd.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.486179Z","iopub.execute_input":"2023-05-05T21:28:17.48648Z","iopub.status.idle":"2023-05-05T21:28:17.526768Z","shell.execute_reply.started":"2023-05-05T21:28:17.486448Z","shell.execute_reply":"2023-05-05T21:28:17.526082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Retorne uma tupla representando a dimensionalidade do DataFrame.\nlabels_pd.shape","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.528126Z","iopub.execute_input":"2023-05-05T21:28:17.528404Z","iopub.status.idle":"2023-05-05T21:28:17.533787Z","shell.execute_reply.started":"2023-05-05T21:28:17.528369Z","shell.execute_reply":"2023-05-05T21:28:17.532917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Retorna os rótulos das colunas do DataFrame.\nlabels_pd.columns","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.536374Z","iopub.execute_input":"2023-05-05T21:28:17.536902Z","iopub.status.idle":"2023-05-05T21:28:17.546348Z","shell.execute_reply.started":"2023-05-05T21:28:17.536857Z","shell.execute_reply":"2023-05-05T21:28:17.545598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Este método imprime informações sobre um DataFrame incluindo o índice dtype e colunas,... \n#...valores não nulos e uso de memória.\nlabels_pd.info()","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.547334Z","iopub.execute_input":"2023-05-05T21:28:17.548021Z","iopub.status.idle":"2023-05-05T21:28:17.576654Z","shell.execute_reply.started":"2023-05-05T21:28:17.547986Z","shell.execute_reply":"2023-05-05T21:28:17.575922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Descrevendo todas as colunas do DataFrame independentemente do tipo de dados.\nlabels_pd.describe(include='all')","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.577877Z","iopub.execute_input":"2023-05-05T21:28:17.578138Z","iopub.status.idle":"2023-05-05T21:28:17.71779Z","shell.execute_reply.started":"2023-05-05T21:28:17.578105Z","shell.execute_reply":"2023-05-05T21:28:17.71706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Incluindo apenas colunas numéricas em um DataFrame descritivo.\n#labels_pd.describe(include=[np.number])","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.719272Z","iopub.execute_input":"2023-05-05T21:28:17.719747Z","iopub.status.idle":"2023-05-05T21:28:17.722937Z","shell.execute_reply.started":"2023-05-05T21:28:17.719711Z","shell.execute_reply":"2023-05-05T21:28:17.72221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hardware de inicialização (CPU / GPU / TPU)\nstrategy = tf.distribute.get_strategy()\n#estratégia de distribuição padrão no Tensorflow. Funciona com CPU e GPU única.\nprint('Running on CPU/GPU')\n    ","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.72431Z","iopub.execute_input":"2023-05-05T21:28:17.724751Z","iopub.status.idle":"2023-05-05T21:28:17.744018Z","shell.execute_reply.started":"2023-05-05T21:28:17.724716Z","shell.execute_reply":"2023-05-05T21:28:17.743359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pré-processamento do conjunto de dados\nBATCH_SIZE = 64\nAUTOTUNE = tf.data.AUTOTUNE\ndef get_image_and_features(image_path, training=True):\n    image = tf.io.decode_image(tf.io.read_file(image_path), dtype=tf.dtypes.float32)\n    image = tf.image.resize_with_crop_or_pad(image, 100, 100) \n    if training:\n        label = tf.strings.split(image_path, os.path.sep)[3] # take the galaxy number from image path\n        galaxyID = int(tf.strings.substr(label, 0, tf.strings.length(label)-4)) # remove .jpg extension\n        galaxy_row = labels_pd.loc[labels_pd['GalaxyID'] == galaxyID]\n        features = tf.cast(galaxy_row.iloc[0,1:].values, tf.float32)\n        return image, features\n    else:\n        return image\n    \ndef dataset_preprocessing(images_path, training=True, tpu=False):\n      \n    images_path_ds = tf.data.Dataset.from_tensor_slices(images_path)\n    if training:\n        dataset = images_path_ds.map(lambda x: tf.py_function(func=get_image_and_features, inp=[x], Tout=(tf.float32,tf.float32)),num_parallel_calls=AUTOTUNE)\n    else:\n        dataset = images_path_ds.map(lambda x: tf.py_function(func=get_image_and_features, inp=[x,False], Tout=tf.float32),num_parallel_calls=AUTOTUNE)\n        \n    \n    dataset = dataset.shuffle(2048) if training else dataset\n    dataset = dataset.batch(BATCH_SIZE) # Set batch size\n    dataset = dataset.prefetch(AUTOTUNE) # Add dataset prefetch() operations to reduce read latency while training the model\n    return dataset\n\nimages_path = tf.io.gfile.glob('../temp/images_training_rev1/*')\nseed = 54\ntf.random.set_seed(seed)\nimages_path = tf.random.shuffle(images_path)\nsamples_size = len(images_path)\nprint(\"Number of total samples: {}\".format(samples_size))\n\n# Dividindo conjunto de dados\nsplitIndex = int(np.floor(samples_size*0.8))\nimages_path_train = images_path[:splitIndex]\nimages_path_val = images_path[splitIndex:]\n#images_path_test = images_path[splitIndex:]\n     \ntrain_dataset = dataset_preprocessing(images_path_train)\nprint('Number of training batches: %d' % tf.data.experimental.cardinality(train_dataset))\n\n#test_dataset = dataset_preprocessing(images_path_test)\n#print('Number of training batches: %d' % tf.data.experimental.cardinality(test_dataset))\n\nval_dataset = dataset_preprocessing(images_path_val)\nprint('Number of validation batches: %d' % tf.data.experimental.cardinality(val_dataset))\n\nprint(\"Dataset preprocessing done!\")","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:17.746111Z","iopub.execute_input":"2023-05-05T21:28:17.746527Z","iopub.status.idle":"2023-05-05T21:28:21.147012Z","shell.execute_reply.started":"2023-05-05T21:28:17.746491Z","shell.execute_reply":"2023-05-05T21:28:21.146278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot example\ndef plot_example(dataset, rows=2, cols=4):\n    fig, axes = plt.subplots(rows, cols, figsize=(12, 6))\n    images = list(dataset.take(1).as_numpy_iterator())[0][0]\n    labels = list(dataset.take(1).as_numpy_iterator())[0][1]\n    for i in range(rows):\n        for j in range(cols):\n            axes[i,j].grid(False)\n            axes[i,j].axis('off')\n            axes[i,j].imshow(images[cols*i+j, :])\n    plt.show()\n    return images[0].shape, labels[0].shape\nimage_shape, features_num = plot_example(train_dataset)\nprint(\"Images shape is: {}\".format(image_shape))\nprint(\"Features length is: {}\".format(features_num))","metadata":{"execution":{"iopub.status.busy":"2023-05-05T21:28:21.148788Z","iopub.execute_input":"2023-05-05T21:28:21.148987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **ConvNet**","metadata":{}},{"cell_type":"markdown","source":"### **Criando a base convolucional**","metadata":{}},{"cell_type":"code","source":"# Modelo\ndef create_model(input_shape, use_augmentation=False):\n    model = tf.keras.models.Sequential(name=\"galaxyClassifier\", layers=[\n        layers.Conv2D(filters=16,kernel_size=(7, 7),activation='relu',input_shape=input_shape),\n        layers.BatchNormalization(),\n        layers.MaxPooling2D(pool_size=(2, 2)),\n        layers.Dropout(0.1),\n        layers.Conv2D(filters=32,kernel_size=(6, 6),activation='relu'),\n        layers.BatchNormalization(),\n        layers.MaxPooling2D(pool_size=(2, 2)),\n        layers.Dropout(0.1),\n        layers.Conv2D(filters=64,kernel_size=(5, 5),activation='relu'),\n        layers.BatchNormalization(),\n        layers.MaxPooling2D(pool_size=(2, 2)),\n        layers.Dropout(0.1),\n        layers.Conv2D(filters=128,kernel_size=(3, 3),activation='relu'),\n        layers.BatchNormalization(),\n        layers.MaxPooling2D(pool_size=(2, 2)),\n        layers.Dropout(0.1),\n        layers.Flatten(),\n        layers.Dense(512, activation='relu'),\n        layers.Dropout(0.2),\n        layers.Dense(256, activation='relu'),\n        layers.Dropout(0.2),\n        layers.Dense(37, activation='sigmoid')\n    ])\n\n    if use_augmentation:\n        data_augmentation = tf.keras.models.Sequential(name='augmentation', layers=[\n            layers.experimental.preprocessing.RandomFlip(\"horizontal_and_vertical\", input_shape=input_shape),\n            layers.experimental.preprocessing.RandomRotation(0.3),\n            layers.experimental.preprocessing.RandomZoom(height_factor=0.2, width_factor=0.2),\n            layers.experimental.preprocessing.RandomContrast(0.05)])\n        model = tf.keras.models.Sequential(name=\"galaxyClassifier\", layers=[\n            data_augmentation,\n            model])\n        \n    return model\n\nwith strategy.scope(): \n    image_shape = (100,100,3)\n    model = create_model(image_shape, True)\n    optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3) # Optimizer\n    loss_func = losses.MeanSquaredError() # Loss function\n    model.compile(loss=loss_func, optimizer=optimizer, metrics=[tf.keras.metrics.RootMeanSquaredError()])\n    \nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Treinamento\nnum_epochs = 10\nverbose = True\n\n# Chamadas de retorno\nreduce_lr = callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=7, min_lr=1e-5)\ndef decay_schedule(epoch, lr):\n    return lr * 0.8 if (epoch % 10 == 0) and (epoch != 0) else lr\nlr_scheduler = callbacks.LearningRateScheduler(decay_schedule)\nearly_stop = callbacks.EarlyStopping(monitor='val_loss',mode='min',verbose=1,patience=7)\ncheckpoint = callbacks.ModelCheckpoint('best_model', save_best_only=True, monitor='val_accuracy', mode='max')\ncallbacksInUse = []\n\nprint('------- Training -------')\nstart = time.time()\nhistory = model.fit(train_dataset, validation_data=val_dataset, epochs=num_epochs, callbacks=callbacksInUse, use_multiprocessing=True, verbose=verbose)\n#history = model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels))\nend = time.time()\nprint(\"Total training took {:.2f} hours.\".format((end - start)/3600))\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Traçar curvas de aprendizagem\nmetrics = history.history\nfig, axes = plt.subplots(1, 2, figsize=(12,6))\naxes[0].plot(metrics['root_mean_squared_error'], label='train_accuracy')\naxes[0].plot(metrics['val_root_mean_squared_error'], label='val_accuracy')\naxes[0].set_xlabel('Epoch')\naxes[0].set_ylabel('RMSE')\naxes[0].legend(loc='upper right')\naxes[1].plot(metrics['loss'], label='train_loss')\naxes[1].plot(metrics['val_loss'], label='val_loss')\naxes[1].set_xlabel('Epoch')\naxes[1].set_ylabel('Loss')\naxes[1].legend(loc='upper right')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Avaliação\nresults = model.evaluate(val_dataset, verbose=1)\nprint(\"Test RMSE: {:.3f}\".format(results[1]))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predição\ntest_images_path = tf.io.gfile.glob('../temp/images_test_rev1/*')\ntest_dataset = dataset_preprocessing(test_images_path,False)\nprint('Number of test batches: %d' % tf.data.experimental.cardinality(test_dataset))\nprint('------- Prediction -------')\nresult = model.predict(test_dataset, verbose=1)\nprint(\"result shape: {}\".format(result.shape))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Modelo pré treinado**","metadata":{}},{"cell_type":"markdown","source":"### **VGG16**","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport zipfile\n\ndef unzip(file, destination):\n    print('Unzipping to', destination)\n    with zipfile.ZipFile(file, 'r') as zip_ref:\n        zip_ref.extractall(destination)\n\nbase_dir = \"/kaggle/tmp/\"\ntrain_images_path = os.path.join(base_dir, \"images_training_rev1\")\ntest_images_path = os.path.join(base_dir, \"images_test_rev1\")\n\nif not os.path.exists(base_dir):\n    unzip('/kaggle/input/galaxy-zoo-the-galaxy-challenge/images_training_rev1.zip', base_dir)\n    unzip('/kaggle/input/galaxy-zoo-the-galaxy-challenge/images_test_rev1.zip', base_dir)\n    unzip('/kaggle/input/galaxy-zoo-the-galaxy-challenge/training_solutions_rev1.zip', base_dir)\n\nfor dirname, _, filenames in os.walk(base_dir):\n    for filename in filenames[:5]:\n        print(os.path.join(dirname, filename))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\ndef append_ext(filename):\n    \"\"\" Appends `.jpg` file extension to a filename \"\"\"\n    return f\"{filename}.jpg\"\n\ntrain_sol = pd.read_csv(\"/kaggle/tmp/training_solutions_rev1.csv\")\ntrain_sol[\"GalaxyID\"] = train_sol[\"GalaxyID\"].apply(append_ext)\ntrain_sol.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Preparação dos Dados**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)\n\ntrain_generator = datagen.flow_from_dataframe(\n    dataframe=train_sol,\n    directory=train_images_path,\n    x_col=\"GalaxyID\",\n    y_col=[\"Class1.1\", \"Class1.2\", \"Class1.3\"],\n    clases=['Elípticas', 'Espiral', 'Irregular'],\n    subset=\"training\",\n    batch_size=32,\n    shuffle=False,\n    class_mode=\"raw\",\n    target_size=(100,100)\n)\n\nvalid_generator = datagen.flow_from_dataframe(\n    dataframe=train_sol,\n    directory=train_images_path,\n    x_col=\"GalaxyID\",\n    y_col=[\"Class1.1\", \"Class1.2\", \"Class1.3\"],\n    subset=\"validation\",\n    batch_size=32,\n    shuffle=False,\n    class_mode=\"raw\",\n    target_size=(100,100)\n)\n\ntrain_steps = np.ceil(train_generator.samples / train_generator.batch_size)\nval_steps = np.ceil(valid_generator.samples / valid_generator.batch_size)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras import layers, Model\nfrom tensorflow.keras.applications.vgg16 import VGG16\n\ndef build_model(num_classes):\n\n    pre_trained_model = VGG16(input_shape=(100,100,3),\n                            weights='imagenet',\n                            include_top=False) \n\n    # Achatar a camada de saída para 1 dimensão\n    x = layers.Flatten()(pre_trained_model.output)\n\n\n    # Adicionar uma camada totalmente conectada com 1024 unidades ocultas e ativação ReLU (x2)\n    x = layers.Dense(1024, activation='relu')(x)\n    x = layers.Dense(1024, activation='relu')(x)\n\n\n    # Adicionar uma taxa de abandono de 0,2\n    x = layers.Dropout(0.2)(x)\n\n\n    # Adicionar uma camada softmax final para classificação\n    output = layers.Dense(num_classes, activation='softmax')(x)\n\n    # Definir o modelo\n    model = Model( pre_trained_model.input, output )\n\n    return model, pre_trained_model\n\nmodel, pre_trained_model = build_model(3)\n#print(model.summary())\n\nfor layer in pre_trained_model.layers:\n    layer.trainable = False\n\n#print(model.summary())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Compilando**","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.optimizers import Adam\nfrom keras import backend as K\n\ndef root_mean_squared_error(y_true, y_pred):\n        return K.sqrt(K.mean(K.square(y_pred - y_true)))\n\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=Adam(lr=1e-3),\n              metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib import pyplot as plt\n\ndef plot_history(history):\n# Recupera uma lista de resultados de precisão em conjuntos de dados de treinamento e teste para cada período de treinamento\n\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n\n    # Recupera uma lista de resultados da lista de dados de treinamento e teste\n    # conjuntos para cada época de treinamento\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    # Obter o número de épocas\n    epochs = range(len(acc))\n\n    # Traçar treino e precisão de validação por época\n    plt.figure(dpi=150)\n    plt.plot(epochs, acc)\n    plt.plot(epochs, val_acc)\n    plt.ylabel('Accuracy')\n    plt.ylim([0,1])\n    plt.legend( ('training', 'validation') )\n    plt.figure()\n\n    # Traçar treinamento e perda de validação por época\n    plt.figure(dpi=150)\n    plt.plot(epochs, loss)\n    plt.plot(epochs, val_loss)\n    plt.ylabel('Loss')\n    plt.title('Training and validation loss')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Treinamento de modelo**","metadata":{}},{"cell_type":"code","source":"tf_history = model.fit_generator(train_generator,\n#                                  steps_per_epoch=256,\n                                 steps_per_epoch=train_steps,\n                                 epochs=10,\n                                 validation_data=valid_generator,\n#                                  validation_steps=256,\n                                 validation_steps=val_steps,\n                                 verbose=2)\n\nplot_history( tf_history )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in pre_trained_model.layers[-5:]:\n    layer.trainable = True\n    \nmodel.compile(loss='categorical_crossentropy',\n              optimizer=Adam(lr=1e-4),\n              metrics=['accuracy'])\n    \ntf_history = model.fit_generator(train_generator,\n#                                  steps_per_epoch=256,\n                                 steps_per_epoch=train_steps,\n                                 epochs=10,\n                                 validation_data=valid_generator,\n#                                  validation_steps=256,\n                                 validation_steps=val_steps,\n                                 verbose=2)\n\nplot_history( tf_history )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer_idx, layer in enumerate(model.layers):\n  # verifica a camada convolucional\n  if not 'convolutional' in str(layer.__class__):\n    continue\n  print(layer_idx, layer.name, layer.output.shape)\n\nvisualization_model = Model(model.input, model.layers[1].output)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualization_model = Model(model.input, model.layers[1].output)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.utils.plot_model(model, show_shapes=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualization_model = Model(model.input, model.layers[1].output)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show(img):\n  '''display image'''\n  plt.figure(figsize=(6,6))\n  plt.grid(False)\n  plt.axis('Off')\n  plt.imshow(img)\n  plt.show()\n\nnext_data = valid_generator.next()\nimg = next_data[0][0]\nshow(img)\n\n# expand dimensions so that it fakes a batch containing a single sample\nimg = np.expand_dims(img, axis=0)\n\nprint(f\"Ground truth:\\t   {next_data[1][0]}\")\nprint(f\"Model prediction: {model.predict(img)}\")\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_maps = visualization_model.predict(img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"square = 8\nfig = plt.gcf()\nfig.set_size_inches(square*2,square*2)\nidx = 1\nfor _ in range(square):\n  for _ in range(square):\n    sp = plt.subplot(square, square, idx)\n    sp.axis('Off')\n    sp.title.set_text(str(idx-1))\n    plt.imshow(feature_maps[0, :, :, idx-1])\n    idx += 1\n\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"layer_indices = [1, 2, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20]\nvisualization_model = Model( model.input, [model.layers[idx].output for idx in layer_indices] )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#@title Plot average feature maps\nplt.imshow(img[0])\nplt.axis('Off')\nplt.title('Input Image')\nplt.show()\n\nfig=plt.figure(figsize=(150, 150))\nfor layer_idx, fmap in enumerate(feature_maps[:5]):\n    sp = fig.add_subplot(1, len(feature_maps), layer_idx+1)\n    sp.axis('Off')\n    sp.title.set_text(model.layers[ layer_indices[layer_idx] ].name)\n    plt.imshow(np.squeeze(fmap.mean(axis=-1)))\n    \nfig=plt.figure(figsize=(150, 150))\nfor layer_idx, fmap in enumerate(feature_maps[5:10]):\n    sp = fig.add_subplot(1, len(feature_maps), layer_idx+1)\n    sp.axis('Off')\n    sp.title.set_text(model.layers[ layer_indices[layer_idx] ].name)\n    plt.imshow(np.squeeze(fmap.mean(axis=-1)))\n    \nfig=plt.figure(figsize=(150, 150))\nfor layer_idx, fmap in enumerate(feature_maps[10:15]):\n    sp = fig.add_subplot(1, len(feature_maps), layer_idx+1)\n    sp.axis('Off')\n    sp.title.set_text(model.layers[ layer_indices[layer_idx] ].name)\n    plt.imshow(np.squeeze(fmap.mean(axis=-1)))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import classification_report, confusion_matrix\n\nY_pred = model.predict_generator(valid_generator, val_steps)\ny_pred = np.argmax(Y_pred, axis=1)\ny_true = np.argmax(valid_generator.labels, axis=1)\n\nprint('Confusion Matrix')\nprint(confusion_matrix(y_true, y_pred))\n\nprint('Classification Report')\ntarget_names = ['Elíptica', 'Espiral', 'Irregular']\nprint(classification_report(y_true, y_pred, target_names=target_names))","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}