{"cells":[{"metadata":{},"cell_type":"markdown","source":"### Welcome to this kernel.In this kernel i am using some sort of attention/related techniques to focus on areas .Before you fork please support and upvote the current kernel and following reference kernels. <br>\n1. https://www.kaggle.com/mathormad/aptos-resnet50-baseline <br>\n2. https://www.kaggle.com/kmader/inceptionv3-for-retinopathy-gpu-hr#Attention-Model <br>\n\n"},{"metadata":{},"cell_type":"markdown","source":"### And i used techiniques refered in [this](https://www.kaggle.com/aakashnain/what-does-a-cnn-see) kernel to visualize what my model is looking at.Beautifully scripted kernel with great explaination go through it for more clarity. <br>"},{"metadata":{},"cell_type":"markdown","source":"### Thanks to the reference kernels authors <br>\n\n* [KeepLearning](https://www.kaggle.com/mathormad) <br>\n* [Kevin Mader](https://www.kaggle.com/kmader) <br>\n* [Nain](https://www.kaggle.com/aakashnain)"},{"metadata":{},"cell_type":"markdown","source":"## Installing efficientnet module"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U '../input/install/efficientnet-0.0.3-py2.py3-none-any.whl'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Importing libraries and data"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport os\nprint(os.listdir(\"../input\"))\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, load_model\nfrom keras.layers import (Activation, Dropout, Flatten, Dense, GlobalMaxPooling2D,\n                          BatchNormalization, Input, Conv2D, GlobalAveragePooling2D,concatenate,Concatenate,multiply, LocallyConnected2D, Lambda)\nfrom keras.callbacks import ModelCheckpoint\nfrom keras import metrics\nfrom keras.optimizers import Adam \nfrom keras import backend as K\nimport keras\nfrom keras.models import Model\nimport matplotlib.pyplot as plt\nfrom efficientnet import EfficientNetB3,EfficientNetB4,EfficientNetB5\nimport skimage.io\nfrom skimage.transform import resize\nimport imgaug as aug\nfrom imgaug import augmenters as iaa\nfrom tqdm import tqdm\nimport PIL\nfrom PIL import Image, ImageOps\nimport cv2\nfrom sklearn.utils import class_weight, shuffle\nfrom keras.losses import binary_crossentropy, categorical_crossentropy\n#from keras.applications.resnet50 import preprocess_input\nfrom keras.applications.densenet import DenseNet121,DenseNet169,preprocess_input\nimport keras.backend as K\nimport tensorflow as tf\nfrom sklearn.metrics import f1_score, fbeta_score, cohen_kappa_score\nfrom keras.utils import Sequence\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nimport imgaug as ia\nimport keras.callbacks as callbacks\nfrom keras.callbacks import Callback\n%config InlineBackend.figure_format=\"svg\"\n%matplotlib inline\n\nWORKERS = 2\nCHANNEL = 3\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nSIZE = 256\nNUM_CLASSES = 5","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ndf_test = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = df_train['id_code']\ny = df_train['diagnosis']\n\nx, y = shuffle(x, y, random_state=8)\ny.hist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y = to_categorical(y, num_classes=NUM_CLASSES)\ntrain_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.15,\n                                                      stratify=y, random_state=8)\nprint(train_x.shape)\nprint(train_y.shape)\nprint(valid_x.shape)\nprint(valid_y.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data Augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"#refernce: https://github.com/aleju/imgaug\nsometimes = lambda aug: iaa.Sometimes(0.5, aug)\nseq = iaa.Sequential(\n        [\n            # apply the following augmenters to most images\n            iaa.Fliplr(0.5), # horizontally flip 50% of all images\n            iaa.Flipud(0.2), # vertically flip 20% of all images\n            sometimes(iaa.Affine(\n                scale={\"x\": (0.9, 1.1), \"y\": (0.9, 1.1)}, # scale images to 80-120% of their size, individually per axis\n                translate_percent={\"x\": (-0.1, 0.1), \"y\": (-0.1, 0.1)}, # translate by -20 to +20 percent (per axis)\n                rotate=(-10, 10), # rotate by -45 to +45 degrees\n                shear=(-5, 5), # shear by -16 to +16 degrees\n                order=[0, 1], # use nearest neighbour or bilinear interpolation (fast)\n                cval=(0, 255), # if mode is constant, use a cval between 0 and 255\n                mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples)\n            )),\n            # execute 0 to 5 of the following (less important) augmenters per image\n            # don't execute all of them, as that would often be way too strong\n            iaa.SomeOf((0, 5),\n                [\n                    sometimes(iaa.Superpixels(p_replace=(0, 1.0), n_segments=(20, 200))), # convert images into their superpixel representation\n                    iaa.OneOf([\n                        iaa.GaussianBlur((0, 1.0)), # blur images with a sigma between 0 and 3.0\n                        iaa.AverageBlur(k=(3, 5)), # blur image using local means with kernel sizes between 2 and 7\n                        iaa.MedianBlur(k=(3, 5)), # blur image using local medians with kernel sizes between 2 and 7\n                    ]),\n                    iaa.Sharpen(alpha=(0, 1.0), lightness=(0.9, 1.1)), # sharpen images\n                    iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)), # emboss images\n                    # search either for all edges or for directed edges,\n                    # blend the result with the original image using a blobby mask\n                    iaa.SimplexNoiseAlpha(iaa.OneOf([\n                        iaa.EdgeDetect(alpha=(0.5, 1.0)),\n                        iaa.DirectedEdgeDetect(alpha=(0.5, 1.0), direction=(0.0, 1.0)),\n                    ])),\n                    iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.01*255), per_channel=0.5), # add gaussian noise to images\n                    iaa.OneOf([\n                        iaa.Dropout((0.01, 0.05), per_channel=0.5), # randomly remove up to 10% of the pixels\n                        iaa.CoarseDropout((0.01, 0.03), size_percent=(0.01, 0.02), per_channel=0.2),\n                    ]),\n                    iaa.Invert(0.01, per_channel=True), # invert color channels\n                    iaa.Add((-2, 2), per_channel=0.5), # change brightness of images (by -10 to 10 of original value)\n                    iaa.AddToHueAndSaturation((-1, 1)), # change hue and saturation\n                    # either change the brightness of the whole image (sometimes\n                    # per channel) or change the brightness of subareas\n                    iaa.OneOf([\n                        iaa.Multiply((0.9, 1.1), per_channel=0.5),\n                        iaa.FrequencyNoiseAlpha(\n                            exponent=(-1, 0),\n                            first=iaa.Multiply((0.9, 1.1), per_channel=True),\n                            second=iaa.ContrastNormalization((0.9, 1.1))\n                        )\n                    ]),\n                    sometimes(iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.25)), # move pixels locally around (with random strengths)\n                    sometimes(iaa.PiecewiseAffine(scale=(0.01, 0.05))), # sometimes move parts of the image around\n                    sometimes(iaa.PerspectiveTransform(scale=(0.01, 0.1)))\n                ],\n                random_order=True\n            )\n        ],\n        random_order=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class My_Generator(Sequence):\n\n    def __init__(self, image_filenames, labels,\n                 batch_size, is_train=True,\n                 mix=False, augment=False):\n        self.image_filenames, self.labels = image_filenames, labels\n        self.batch_size = batch_size\n        self.is_train = is_train\n        self.is_augment = augment\n        if(self.is_train):\n            self.on_epoch_end()\n        self.is_mix = mix\n\n    def __len__(self):\n        return int(np.ceil(len(self.image_filenames) / float(self.batch_size)))\n\n    def __getitem__(self, idx):\n        batch_x = self.image_filenames[idx * self.batch_size:(idx + 1) * self.batch_size]\n        batch_y = self.labels[idx * self.batch_size:(idx + 1) * self.batch_size]\n\n        if(self.is_train):\n            return self.train_generate(batch_x, batch_y)\n        return self.valid_generate(batch_x, batch_y)\n\n    def on_epoch_end(self):\n        if(self.is_train):\n            self.image_filenames, self.labels = shuffle(self.image_filenames, self.labels)\n        else:\n            pass\n    \n    def mix_up(self, x, y):\n        lam = np.random.beta(0.2, 0.4)\n        ori_index = np.arange(int(len(x)))\n        index_array = np.arange(int(len(x)))\n        np.random.shuffle(index_array)        \n        \n        mixed_x = lam * x[ori_index] + (1 - lam) * x[index_array]\n        mixed_y = lam * y[ori_index] + (1 - lam) * y[index_array]\n        \n        return mixed_x, mixed_y\n\n    def train_generate(self, batch_x, batch_y):\n        batch_images = []\n        for (sample, label) in zip(batch_x, batch_y):\n            img = cv2.imread('../input/aptos2019-blindness-detection/train_images/'+sample+'.png')\n            img = cv2.resize(img, (SIZE, SIZE))\n            if(self.is_augment):\n                img = seq.augment_image(img)\n            batch_images.append(img)\n        batch_images = np.array(batch_images, np.float32) / 255\n        batch_y = np.array(batch_y, np.float32)\n        if(self.is_mix):\n            batch_images, batch_y = self.mix_up(batch_images, batch_y)\n        return batch_images, batch_y\n\n    def valid_generate(self, batch_x, batch_y):\n        batch_images = []\n        for (sample, label) in zip(batch_x, batch_y):\n            img = cv2.imread('../input/aptos2019-blindness-detection/train_images/'+sample+'.png')\n            img = cv2.resize(img, (SIZE, SIZE))\n            batch_images.append(img)\n        batch_images = np.array(batch_images, np.float32) / 255\n        batch_y = np.array(batch_y, np.float32)\n        return batch_images, batch_y\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Basemodel - EfficientnetB5"},{"metadata":{"trusted":true},"cell_type":"code","source":"in_lay = Input(shape=(256,256,3))\nbase_model = EfficientNetB5(weights=None,\n    input_shape=(SIZE,SIZE,3),\n    include_top=False\n                   )\nbase_model.load_weights(\"../input/efficientnet-keras-weights-b0b5/efficientnet-b5_imagenet_1000_notop.h5\")\npt_depth = base_model.get_output_shape_at(0)[-1]\npt_features = base_model(in_lay)\nbn_features = BatchNormalization()(pt_features)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Attention model"},{"metadata":{"trusted":true},"cell_type":"code","source":"# here we do an attention mechanism to turn pixels in the GAP on an off\nattn_layer = Conv2D(64, kernel_size = (1,1), padding = 'same', activation = 'relu')(Dropout(0.5)(bn_features))\nattn_layer = Conv2D(16, kernel_size = (1,1), padding = 'same', activation = 'relu')(attn_layer)\nattn_layer = Conv2D(8, kernel_size = (1,1), padding = 'same', activation = 'relu')(attn_layer)\nattn_layer = Conv2D(1, \n                    kernel_size = (1,1), \n                    padding = 'valid', \n                    activation = 'sigmoid')(attn_layer)\n# fan it out to all of the channels\nup_c2_w = np.ones((1, 1, 1, pt_depth))\nup_c2 = Conv2D(pt_depth, kernel_size = (1,1), padding = 'same', \n               activation = 'linear', use_bias = False, weights = [up_c2_w])\nup_c2.trainable = False\nattn_layer = up_c2(attn_layer)\n\nmask_features = multiply([attn_layer, bn_features])\ngap_features = GlobalAveragePooling2D()(mask_features)\ngap_mask = GlobalAveragePooling2D()(attn_layer)\n# to account for missing values from the attention model\ngap = Lambda(lambda x: x[0]/x[1], name = 'RescaleGAP')([gap_features, gap_mask])\ngap_dr = Dropout(0.25)(gap)\ndr_steps = Dropout(0.25)(Dense(128, activation = 'relu')(gap_dr))\nout_layer = Dense(5, activation = 'softmax')(dr_steps)\nretina_model = Model(inputs = [in_lay], outputs = [out_layer])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"retina_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import (ModelCheckpoint, LearningRateScheduler,\n                             EarlyStopping, ReduceLROnPlateau,CSVLogger)\n\nepochs = 30; batch_size = 16\ncheckpoint = ModelCheckpoint('../working/model_.h5', monitor='val_loss', verbose=1, \n                             save_best_only=True, mode='min', save_weights_only = True)\nreduceLROnPlat = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=4, \n                                   verbose=1, mode='auto', epsilon=0.0001)\nearly = EarlyStopping(monitor=\"val_loss\", \n                      mode=\"min\", \n                      patience=9)\ncsv_logger = CSVLogger(filename='../working/training_log.csv',\n                       separator=',',\n                       append=True)\n\ntrain_generator = My_Generator(train_x, train_y, 128, is_train=True)\ntrain_mixup = My_Generator(train_x, train_y, batch_size, is_train=True, mix=False, augment=True)\nvalid_generator = My_Generator(valid_x, valid_y, batch_size, is_train=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# reference link: https://www.kaggle.com/christofhenkel/weighted-kappa-loss-for-keras-tensorflow\ndef kappa_loss(y_true, y_pred, y_pow=2, eps=1e-12, N=5, bsize=32, name='kappa'):\n    with tf.name_scope(name):\n        y_true = tf.to_float(y_true)\n        repeat_op = tf.to_float(tf.tile(tf.reshape(tf.range(0, N), [N, 1]), [1, N]))\n        repeat_op_sq = tf.square((repeat_op - tf.transpose(repeat_op)))\n        weights = repeat_op_sq / tf.to_float((N - 1) ** 2)\n    \n        pred_ = y_pred ** y_pow\n        try:\n            pred_norm = pred_ / (eps + tf.reshape(tf.reduce_sum(pred_, 1), [-1, 1]))\n        except Exception:\n            pred_norm = pred_ / (eps + tf.reshape(tf.reduce_sum(pred_, 1), [bsize, 1]))\n    \n        hist_rater_a = tf.reduce_sum(pred_norm, 0)\n        hist_rater_b = tf.reduce_sum(y_true, 0)\n    \n        conf_mat = tf.matmul(tf.transpose(pred_norm), y_true)\n    \n        nom = tf.reduce_sum(weights * conf_mat)\n        denom = tf.reduce_sum(weights * tf.matmul(\n            tf.reshape(hist_rater_a, [N, 1]), tf.reshape(hist_rater_b, [1, N])) /\n                              tf.to_float(bsize))\n    \n        return nom*0.5 / (denom + eps) + categorical_crossentropy(y_true, y_pred)*0.5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import Callback\nclass QWKEvaluation(Callback):\n    def __init__(self, validation_data=(), batch_size=64, interval=1):\n        super(Callback, self).__init__()\n\n        self.interval = interval\n        self.batch_size = batch_size\n        self.valid_generator, self.y_val = validation_data\n        self.history = []\n\n    def on_epoch_end(self, epoch, logs={}):\n        if epoch % self.interval == 0:\n            y_pred = self.model.predict_generator(generator=self.valid_generator,\n                                                  steps=np.ceil(float(len(self.y_val)) / float(self.batch_size)),\n                                                  workers=1, use_multiprocessing=False,\n                                                  verbose=1)\n            def flatten(y):\n                return np.argmax(y, axis=1).reshape(-1)\n            \n            score = cohen_kappa_score(flatten(self.y_val),\n                                      flatten(y_pred),\n                                      labels=[0,1,2,3,4],\n                                      weights='quadratic')\n            print(\"\\n epoch: %d - QWK_score: %.6f \\n\" % (epoch+1, score))\n            self.history.append(score)\n            if score >= max(self.history):\n                print('saving checkpoint: ', score)\n                self.model.save('../working/model_bestqwk.h5')\n\nqwk = QWKEvaluation(validation_data=(valid_generator, valid_y),\n                    batch_size=batch_size, interval=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# warm up model\nfor layer in retina_model.layers:\n    layer.trainable = False\n\nfor i in range(-3,0):\n    retina_model.layers[i].trainable = True\n\nretina_model.compile(\n    loss='categorical_crossentropy',\n    optimizer=Adam(1e-3))\n\nretina_model.fit_generator(\n    train_generator,\n    steps_per_epoch=np.ceil(float(len(train_y)) / float(128)),\n    epochs=2,\n    workers=WORKERS, use_multiprocessing=True,\n    verbose=1,\n    callbacks=[qwk])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train all layers\nfor layer in retina_model.layers:\n    layer.trainable = True\ncallbacks_list = [checkpoint, csv_logger, reduceLROnPlat, early, qwk]\nretina_model.compile(#loss='categorical_crossentropy',\n            loss=kappa_loss,\n            optimizer=Adam(lr=1e-4))\nretina_model.fit_generator(\n    train_mixup,\n    steps_per_epoch=np.ceil(float(len(train_x)) / float(batch_size)),\n    validation_data=valid_generator,\n    validation_steps=np.ceil(float(len(valid_x)) / float(batch_size)),\n    epochs=epochs,\n    verbose=1,\n    workers=1, use_multiprocessing=False,\n    callbacks=callbacks_list)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Lets see what does our model is looking at!"},{"metadata":{},"cell_type":"markdown","source":"#### Here, we will explore two methods that are very simple to use and can give some good insights about model predictions. These are:\n\n* Visualizing the intermediate layers outputs\n* Class Activation Mapping"},{"metadata":{"trusted":true},"cell_type":"code","source":"outputs = [layer.output for layer in retina_model.layers[2:17]]\n\n# Define a new model that generates the above output\nvis_model = Model(retina_model.input, outputs)\n\n# check if we have all the layers we require for visualization \nvis_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"layer_names = []\nfor layer in outputs:\n    layer_names.append(layer.name.split(\"/\")[0])\n\nprint(\"Layers going to be used for visualization: \")\nprint(layer_names)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Lets see the heatmap generated over the last convolution layer output."},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_CAM(processed_image, predicted_label):\n    \"\"\"\n    This function is used to generate a heatmap for a sample image prediction.\n    \n    Args:\n        processed_image: any sample image that has been pre-processed using the \n                       `preprocess_input()`method of a keras model\n        predicted_label: label that has been predicted by the network for this image\n    \n    Returns:\n        heatmap: heatmap generated over the last convolution layer output \n    \"\"\"\n    # we want the activations for the predicted label\n    predicted_output = retina_model.output[:, predicted_label]\n    \n    # choose the last conv layer in your model\n    last_conv_layer = retina_model.layers[-9]\n    print(retina_model.layers[-9])\n    \n    # get the gradients wrt to the last conv layer\n    grads = K.gradients(predicted_output, last_conv_layer.output)[0]\n    \n    # take mean gradient per feature map\n    grads = K.mean(grads, axis=(0,1,2))\n    \n    # Define a function that generates the values for the output and gradients\n    evaluation_function = K.function([retina_model.input], [grads, last_conv_layer.output[0]])\n    \n    # get the values\n    grads_values, conv_ouput_values = evaluation_function([processed_image])\n    \n    # iterate over each feature map in yout conv output and multiply\n    # the gradient values with the conv output values. This gives an \n    # indication of \"how important a feature is\"\n    for i in range(2048): # we have 2048 features in our last conv layer\n        conv_ouput_values[:,:,i] *= grads_values[i]\n    \n    # create a heatmap\n    heatmap = np.mean(conv_ouput_values, axis=-1)\n    \n    # remove negative values\n    heatmap = np.maximum(heatmap, 0)\n    \n    # normalize\n    heatmap /= heatmap.max()\n    \n    return heatmap","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_random_sample(idx):\n    \"\"\"\n    This function is used to select a random sample from the validation dataframe.\n    It generates prediction for the same. It also stores the heatmap and the intermediate\n    layers activation maps.\n    \n    Arguments:\n        idx: random index to select a sample from validation data\n    \n    Returns:\n        activations: activation values for intermediate layers\n    \"\"\"\n    # select the sample and read the corresponding image and label\n    img_id = df_train.iloc[idx]['id_code']\n    img_path = '../input/aptos2019-blindness-detection/train_images/'+str(img_id)+'.png'\n    sample_image = cv2.imread(img_path)\n    sample_image = cv2.cvtColor(sample_image, cv2.COLOR_BGR2RGB)\n    sample_image = cv2.resize(sample_image, (256, 256))\n    sample_label = df_train.iloc[idx][\"diagnosis\"]\n    \n    # pre-process the image\n    sample_image_processed = np.expand_dims(sample_image, axis=0)\n    sample_image_processed = preprocess_input(sample_image_processed)\n    \n    # generate activation maps from the intermediate layers using the visualization model\n    activations = vis_model.predict(sample_image_processed)\n  \n    \n    # get the label predicted by our original model\n    pred_label = np.argmax(retina_model.predict(sample_image_processed), axis=-1)[0]\n    \n    # choose any random activation map from the activation maps \n    sample_activation = activations[1][0,:,:,8]\n    \n    # normalize the sample activation map\n    sample_activation-=sample_activation.mean()\n    sample_activation/=sample_activation.std()\n    \n    # convert pixel values between 0-255\n    sample_activation *=255\n    sample_activation = np.clip(sample_activation, 0, 255).astype(np.uint8)\n\n    # get the heatmap for class activation map(CAM)\n    heatmap = get_CAM(sample_image_processed, pred_label)\n    heatmap = cv2.resize(heatmap, (sample_image.shape[0], sample_image.shape[1]))\n    heatmap = heatmap *255\n    heatmap = np.clip(heatmap, 0, 255).astype(np.uint8)\n    heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)\n    super_imposed_image = heatmap * 0.5 + sample_image\n    super_imposed_image = np.clip(super_imposed_image, 0,255).astype(np.uint8)\n\n    f,ax = plt.subplots(2,2, figsize=(10,8))\n    ax[0,0].imshow(sample_image)\n    ax[0,0].set_title(f\"True label: {sample_label} \\n Predicted label: {pred_label}\")\n    ax[0,0].axis('off')\n    \n    ax[0,1].imshow(sample_activation)\n    ax[0,1].set_title(\"Random feature map\")\n    ax[0,1].axis('off')\n    \n    ax[1,0].imshow(heatmap)\n    ax[1,0].set_title(\"Class Activation Map\")\n    ax[1,0].axis('off')\n    \n    ax[1,1].imshow(super_imposed_image)\n    ax[1,1].set_title(\"Activation map superimposed\")\n    ax[1,1].axis('off')\n    plt.show()\n    \n    return activations","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"activations= show_random_sample(55)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Lets see the 4 convolution layers('conv2d_156','conv2d_157','conv2d_158','conv2d_159') intermediate activation maps."},{"metadata":{"trusted":true},"cell_type":"code","source":"def visualize_intermediate_activations(layer_names, activations):\n    \"\"\"\n    This function is used to visualize all the itermediate activation maps\n    \n    Arguments:\n        layer_names: list of names of all the intermediate layers we chose\n        activations: all the intermediate activation maps \n    \"\"\"\n    assert len(layer_names)==len(activations), \"Make sure layers and activation values match\"\n    images_per_row=16\n    \n    for layer_name, layer_activation in zip(layer_names[2:6], activations):\n        nb_features = layer_activation.shape[-1]\n        size= layer_activation.shape[1]\n\n        nb_cols = nb_features // images_per_row\n        grid = np.zeros((size*nb_cols, size*images_per_row))\n\n        for col in range(nb_cols):\n            for row in range(images_per_row):\n                feature_map = layer_activation[0,:,:,col*images_per_row + row]\n                feature_map -= feature_map.mean()\n                feature_map /= feature_map.std()\n                feature_map *=255\n                feature_map = np.clip(feature_map, 0, 255).astype(np.uint8)\n\n                grid[col*size:(col+1)*size, row*size:(row+1)*size] = feature_map\n\n        scale = 1./size\n        plt.figure(figsize=(scale*grid.shape[1], scale*grid.shape[0]))\n        plt.title(layer_name)\n        plt.grid(False)\n        plt.imshow(grid, aspect='auto', cmap='viridis')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_intermediate_activations(activations=activations, layer_names=layer_names)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Making predictions"},{"metadata":{"trusted":true},"cell_type":"code","source":"submit = pd.read_csv('../input/aptos2019-blindness-detection/sample_submission.csv')\nretina_model.load_weights('../working/model_bestqwk.h5')\npredicted = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i, name in tqdm(enumerate(submit['id_code'])):\n    path = os.path.join('../input/aptos2019-blindness-detection/test_images/', name+'.png')\n    image = cv2.imread(path)\n    image = cv2.resize(image, (SIZE, SIZE))\n    score_predict = retina_model.predict((image[np.newaxis])/255)\n    label_predict = np.argmax(score_predict)\n    predicted.append(str(label_predict))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submit['diagnosis'] = predicted\nsubmit.to_csv('submission.csv', index=False)\nsubmit.head()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}