{"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 tensorflow as tf\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras import layers, metrics, losses, callbacks, regularizers\nfrom tensorflow.python.client import device_lib\nfrom sklearn.model_selection import train_test_split\nfrom kaggle_datasets import KaggleDatasets\nplt.rc('figure', autolayout=True)\nplt.rc('axes', labelweight='bold', labelsize='large',titleweight='bold', titlesize=18, titlepad=10)\nplt.rc('image', cmap='magma')","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":4.557406,"end_time":"2021-08-25T08:12:51.175525","exception":false,"start_time":"2021-08-25T08:12:46.618119","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-23T15:21:32.504583Z","iopub.execute_input":"2021-12-23T15:21:32.505063Z","iopub.status.idle":"2021-12-23T15:21:37.95769Z","shell.execute_reply.started":"2021-12-23T15:21:32.504981Z","shell.execute_reply":"2021-12-23T15:21:37.956832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Baixar 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\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":"2021-12-23T15:21:37.960174Z","iopub.execute_input":"2021-12-23T15:21:37.960808Z"},"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":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pré-processamento de 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    #dataset = images_path_ds.map(get_image_and_features, num_parallel_calls=tf.data.AUTOTUNE)\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# Dividir conjuntos de validação de trem\nsplitIndex = int(np.floor(samples_size*0.8))\nimages_path_train = images_path[:splitIndex]\nimages_path_val = images_path[splitIndex:]\n     \ntrain_dataset = dataset_preprocessing(images_path_train)\nprint('Number of training batches: %d' % tf.data.experimental.cardinality(train_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":{"papermill":{"duration":3.715617,"end_time":"2021-08-25T08:13:17.136783","exception":false,"start_time":"2021-08-25T08:13:13.421166","status":"completed"},"tags":[],"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n","metadata":{"papermill":{"duration":2.318482,"end_time":"2021-08-25T08:13:19.492136","exception":false,"start_time":"2021-08-25T08:13:17.173654","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-18T04:29:15.677079Z","iopub.execute_input":"2021-12-18T04:29:15.677434Z"}}},{"cell_type":"code","source":"# Plot example 2\ndef plot_example(dataset, rows=2, cols=2):\n    fig, axes = plt.subplots(rows, cols, figsize=(24, 12))\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":{"trusted":true},"execution_count":null,"outputs":[]},{"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=(6, 6),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=(3, 3),activation='relu'),\n        layers.BatchNormalization(),\n        layers.MaxPooling2D(pool_size=(2, 2)),\n        layers.Dropout(0.1),\n        layers.Conv2D(filters=64,kernel_size=(3, 3),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":{"papermill":{"duration":0.449897,"end_time":"2021-08-25T08:13:19.983119","exception":false,"start_time":"2021-08-25T08:13:19.533222","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Treinamento\nnum_epochs = 10\nverbose = True\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)\nend = time.time()\nprint(\"Total training took {:.2f} hours.\".format((end - start)/3600))\n\n# 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":{"papermill":{"duration":395.850426,"end_time":"2021-08-25T08:19:55.874824","exception":false,"start_time":"2021-08-25T08:13:20.024398","status":"completed"},"tags":[],"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":{"papermill":{"duration":2.634409,"end_time":"2021-08-25T08:20:00.056127","exception":false,"start_time":"2021-08-25T08:19:57.421718","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Savar modelo\noutPath = model.name+\".h5\"\nmodel.save(outPath)\nprint(\"Model is saved: {}\".format(outPath))\n\n#model.load_weights('../input/models/galaxyClassifier1.h5')\nprint(\"Model is loaded succesfully!\")","metadata":{"papermill":{"duration":1.581862,"end_time":"2021-08-25T08:20:07.413816","exception":false,"start_time":"2021-08-25T08:20:05.831954","status":"completed"},"tags":[],"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":"## VGG19","metadata":{}},{"cell_type":"code","source":"import numpy as np #álgebra Linear\nimport pandas as pd #processamento de dados, E / S de arquivo CSV\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":"markdown","source":"### Descompactando os Dados","metadata":{}},{"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))\n","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=['Early type', 'Spiral', 'Artifact'],\n    subset=\"training\",\n    batch_size=32,\n    shuffle=False,\n    class_mode=\"raw\",\n    target_size=(224,224)\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=(224,224)\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":"markdown","source":"### Modelo","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras import layers, Model\nfrom tensorflow.keras.applications.vgg19 import VGG19\nfrom tensorflow.keras.applications.resnet50 import ResNet50\n\ndef build_model(num_classes):\n\n    pre_trained_model = VGG19(input_shape=(224,224,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)\nprint(model.summary())\n\nfor layer in pre_trained_model.layers:\n    layer.trainable = False\n\nprint(model.summary())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Compilando o modelo","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 \n    #...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=5,\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":"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)}\")","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\n# plt.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 feature maps\nplt.imshow(img[0])\nplt.axis('Off')\nplt.title('Input Image')\nplt.show()\n\nsquare = 8\nfeature_maps = visualization_model.predict(img)\nfor layer_idx, fmap in enumerate(feature_maps):\n    fig = plt.gcf()\n    fig.set_size_inches(square*2, square*2)\n    fig.suptitle(model.layers[layer_indices[layer_idx]].name)\n    idx = 0\n    \n    for _ in range(square):\n        for _ in range(2):\n            fm = fmap[0, :, :, idx]\n            sp = plt.subplot(square, square, idx+1)\n            sp.axis('Off')\n            sp.title.set_text(str(idx))\n            plt.imshow(fm)\n            idx += 1\n\n    plt.show()","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=(100, 100))\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=(100, 100))\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=(100, 100))\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 = ['Early type', 'Spiral', 'Artifact']\nprint(classification_report(y_true, y_pred, target_names=target_names))","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}