{"cells":[{"metadata":{},"cell_type":"markdown","source":"This notebook presents the code for training the EfficientNetB7 model on Google TPU accelerator with various augmentations and visualization of the main steps of data processing and model training. "},{"metadata":{},"cell_type":"markdown","source":"- This work is based on two published notebooks, so please, upvote their:\n    - pipeline was taken from @maksymshkliarevskyi notebook;\n    - Needle augmentation was taken from @khoongweihao notebook"},{"metadata":{},"cell_type":"markdown","source":"<a id=\"start\"></a>\n<h2 style='color:#0A0502; background:white; border:2px solid #0A0502'><center>Table of contents:</center></h2>\n\n* [**Data preprocessing**](#1)\n* [**Augmentations**](#2)\n* [**Model preparation**](#3)\n* [**Model training**](#4)\n* [**Visualization of CNN intermediate activations**](#5)\n* [**Prediction**](#6)"},{"metadata":{"trusted":true},"cell_type":"code","source":"# install the latest version of pip installer\n!pip install --upgrade pip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# install library with efficientnet architecture\n!pip install -q efficientnet","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import re,os,cv2,random\n\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\nfrom kaggle_datasets import KaggleDatasets\nimport tensorflow as tf\nimport albumentations as A\nfrom sklearn.model_selection import train_test_split\n\n# importing neural network architecture\nfrom efficientnet.tfkeras import EfficientNetB7\n\n# importing other useful tools: layers, optimizers, loss functions\nfrom tensorflow.keras.layers import Flatten,Dense,Dropout,BatchNormalization\nfrom tensorflow.keras.models import Model,Sequential\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras import models, layers\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization\nfrom keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint\n\n# ignoring warnings\nimport warnings\nwarnings.simplefilter(\"ignore\")\n\n%matplotlib inline \nprint(\"Tensorflow version \" + tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### What is a TPU?\n\nTo accelerate the largest-scale machine learning (ML) applications deployed today and enable rapid development of the ML applications of tomorrow, Google created custom silicon chips called Tensor Processing Units ([TPUs](https://cloud.google.com/tpu/docs/tpus)). When assembled into multi-rack ML supercomputers called Cloud TPU Pods.\n\n\n<center><img src=\"https://miro.medium.com/max/890/1*16HkeV33jzWruFoVYokVlQ.png\" width=\"400\"></center>\n<br>\n\n\n#### What’s in a Cloud TPU\nA single Cloud TPU Pod can include more than 1,000 individual TPU chips which are connected by an ultra-fast, two-dimensional toroidal mesh network, as illustrated below. The TPU software stack uses this mesh network to enable many racks of machines to be programmed as a single, giant ML supercomputer via a variety of flexible, high-level APIs.\n\n\n\n\nReferences:\n- [Use TPUs](https://www.tensorflow.org/guide/tpu)\n- [Better performance with the tf.data API](https://www.tensorflow.org/guide/data_performance)\n- [Custom training with tf.distribute.Strategy](https://www.tensorflow.org/tutorials/distribute/custom_training)\n- [Cloud TPU](https://cloud.google.com/tpu)\n- [Google’s scalable supercomputers for machine learning, Cloud TPU Pods, are now publicly available in beta](https://cloud.google.com/blog/products/ai-machine-learning/googles-scalable-supercomputers-for-machine-learning-cloud-tpu-pods-are-now-publicly-available-in-beta)"},{"metadata":{"trusted":true},"cell_type":"code","source":"# TPU or GPU detection\n# detect hardware, return appropriate distribution strategy\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print(f'Running on TPU: {tpu.master()}')\nexcept ValueError:\n    tpu = None\n    print('Running on GPU')\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy()\n\nREPLICAS = strategy.num_replicas_in_sync\nprint(f'Number of replicas: {REPLICAS}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"1\"></a>\n<h1 style='color:#0A0502; background:white; border:0'><center>Data preprocessing</center></h1>\n\n[**Back to the table of contents**](#start)"},{"metadata":{"trusted":true},"cell_type":"code","source":"WORK_DIR = '../input/ranzcr-clip-catheter-line-classification'\nos.listdir(WORK_DIR)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# data connection\nGCS_DS_PATH = KaggleDatasets().get_gcs_path('ranzcr-clip-catheter-line-classification')\n\ntrain = pd.read_csv(os.path.join(WORK_DIR, \"train.csv\"))\ntrain_images = GCS_DS_PATH + \"/train/\" + train['StudyInstanceUID'] + '.jpg'\n\nss = pd.read_csv(os.path.join(WORK_DIR, 'sample_submission.csv'))\ntest_images = GCS_DS_PATH + \"/test/\" + ss['StudyInstanceUID'] + '.jpg'\n\nlabel_cols = ss.columns[1:]\nlabels = train[label_cols].values\n\ntrain_annot = pd.read_csv(os.path.join(WORK_DIR, \"train_annotations.csv\"))\n\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# show label classes\nsns.set_style(\"whitegrid\")\nfig = plt.figure(figsize = (15, 12), dpi = 600)\nplt.suptitle('Labels count', fontfamily = 'serif', size = 20)\n\nfor ind, i in enumerate(label_cols):\n    fig.add_subplot(4, 3, ind + 1)\n\n    sns.countplot(train[i], edgecolor = 'black',\n                  palette = reversed(sns.color_palette('viridis', 2)))\n    \n    plt.xlabel('')\n    plt.ylabel('')\n    plt.xticks(fontfamily = 'serif', size = 12)\n    plt.yticks(fontfamily = 'serif', size = 12)\n    plt.title(i, fontfamily = 'serif', size = 12)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# show some images\nsample = train.sample(9)\nplt.figure(figsize=(10, 7), dpi = 600)\nfor ind, image_id in enumerate(sample.StudyInstanceUID):\n    plt.subplot(3, 3, ind + 1)\n    image = image_id + '.jpg'\n    img = cv2.imread(os.path.join(WORK_DIR, \"train\", image))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.title('Shape: {}'.format(img.shape[:2]))\n    plt.axis(\"off\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"row = train_annot.iloc[8]\nimage_path = os.path.join(WORK_DIR, \"train\", row[\"StudyInstanceUID\"] + \".jpg\")\nchosen_image = cv2.imread(image_path)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"2\"></a>\n<h1 style='color:#0A0502; background:white; border:0'><center>Augmentations</center></h1>\n\n[**Back to the table of contents**](#start)"},{"metadata":{},"cell_type":"markdown","source":"### Albumentations library"},{"metadata":{},"cell_type":"markdown","source":"Let's see what our training data would look like using the Albumentations library."},{"metadata":{"trusted":true},"cell_type":"code","source":"albumentation_list = [A.RandomSunFlare(p=1), \n                      A.RandomFog(p=1), \n                      A.RandomBrightness(p=1),\n                      A.RandomCrop(p=1,height = 512, width = 512), \n                      A.Rotate(p=1, limit=90),\n                      A.RGBShift(p=1), \n                      A.RandomSnow(p=1),\n                      A.HorizontalFlip(p=1), \n                      A.VerticalFlip(p=1), \n                      A.RandomContrast(limit = 0.5,p = 1),\n                      A.HueSaturationValue(p=1,hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=50),\n                      A.Cutout(p=1),\n                      A.Transpose(p=1), \n                      A.JpegCompression(p=1),\n                      A.CoarseDropout(p=1),\n                      A.IAAAdditiveGaussianNoise(loc=0, scale=(2.5500000000000003, 12.75), per_channel=False, p=1),\n                      A.IAAAffine(scale=1.0, translate_percent=None, translate_px=None, rotate=0.0, shear=0.0, order=1, cval=0, mode='reflect', p=1),\n                      A.IAAAffine(rotate=90., p=1),\n                      A.IAAAffine(rotate=180., p=1)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_matrix_list = []\nbboxes_list = []\nfor aug_type in albumentation_list:\n    img = aug_type(image = chosen_image)['image']\n    img_matrix_list.append(img)\n\nimg_matrix_list.insert(0,chosen_image)    \n\ntitles_list = [\"Original\",\"RandomSunFlare\",\"RandomFog\",\"RandomBrightness\",\n               \"RandomCrop\",\"Rotate\", \"RGBShift\", \"RandomSnow\",\"HorizontalFlip\", \"VerticalFlip\", \"RandomContrast\",\"HSV\",\n               \"Cutout\",\"Transpose\",\"JpegCompression\",\"CoarseDropout\",\"IAAAdditiveGaussianNoise\",\"IAAAffine\",\"IAAAffineRotate90\",\"IAAAffineRotate180\"]\n\ndef plot_multiple_img(img_matrix_list, title_list, ncols, nrows=5,  main_title=\"\"):\n    fig, myaxes = plt.subplots(figsize=(20, 15), nrows=nrows, ncols=ncols, squeeze=False)\n    fig.suptitle(main_title, fontsize = 30)\n    fig.subplots_adjust(wspace=0.3)\n    fig.subplots_adjust(hspace=0.3)\n    for i, (img, title) in enumerate(zip(img_matrix_list, title_list)):\n        myaxes[i // ncols][i % ncols].imshow(img)\n        myaxes[i // ncols][i % ncols].set_title(title, fontsize=15)\n    plt.show()\n    \nplot_multiple_img(img_matrix_list, titles_list, ncols = 4,main_title=\"Different Types of Augmentations with Albumentations\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Xray Needle Augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"def NeedleAugmentation(image, n_needles=2, dark_needles=False, p=0.5, needle_folder='../input/xray-needle-augmentation'):\n    aug_prob = random.random()\n    if aug_prob < p:\n        height, width, _ = image.shape  # target image width and height\n        needle_images = [im for im in os.listdir(needle_folder) if 'png' in im]\n\n        for _ in range(1, n_needles):\n            needle = cv2.cvtColor(cv2.imread(os.path.join(needle_folder, random.choice(needle_images))), cv2.COLOR_BGR2RGB)\n            needle = cv2.flip(needle, random.choice([-1, 0, 1]))\n            needle = cv2.rotate(needle, random.choice([0, 1, 2]))\n\n            h_height, h_width, _ = needle.shape  # needle image width and height\n            roi_ho = random.randint(0, abs(image.shape[0] - needle.shape[0]))\n            roi_wo = random.randint(0, abs(image.shape[1] - needle.shape[1]))\n            roi = image[roi_ho:roi_ho + h_height, roi_wo:roi_wo + h_width]\n\n            # Creating a mask and inverse mask \n            img2gray = cv2.cvtColor(needle, cv2.COLOR_BGR2GRAY)\n            ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)\n            mask_inv = cv2.bitwise_not(mask)\n\n            # Now black-out the area of needle in ROI\n            img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)\n\n            # Take only region of insect from insect image.\n            if dark_needles:\n                img_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)\n                needle_fg = cv2.bitwise_and(img_bg, img_bg, mask=mask)\n            else:\n                needle_fg = cv2.bitwise_and(needle, needle, mask=mask)\n\n            # Put needle in ROI and modify the target image\n            dst = cv2.add(img_bg, needle_fg, dtype=cv2.CV_64F)\n\n            image[roi_ho:roi_ho + h_height, roi_wo:roi_wo + h_width] = dst\n\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# orginal needles\nchosen_image = cv2.imread(image_path)\naug_image = NeedleAugmentation(chosen_image, n_needles=3, dark_needles=False, p=1.0)\nplt.imshow(aug_image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# dark needles (just black, dark, sinister as it is on an Xray)\nchosen_image = cv2.imread(image_path)\naug_image = NeedleAugmentation(chosen_image, n_needles=3, dark_needles=True, p=1.0)\nplt.imshow(aug_image)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### TensorFlow augmentations"},{"metadata":{"trusted":true},"cell_type":"code","source":"chosen_image = cv2.imread(image_path)\n\ntf_trans_list = [\n    tf.image.rot90(chosen_image, k=1), # 90 degrees counter-clockwise\n    tf.image.rot90(chosen_image, k=2), # 180 degrees counter-clockwise\n    tf.image.rot90(chosen_image, k=3), # 270 degrees counter-clockwise\n    tf.image.random_brightness(chosen_image, 0.5), \n    tf.image.random_contrast(chosen_image, 0.2, 0.5), \n    tf.image.random_flip_left_right(chosen_image, seed=42),\n    tf.image.random_flip_up_down(chosen_image, seed=42),\n    tf.image.random_hue(chosen_image, 0.5),\n    tf.image.random_jpeg_quality(chosen_image, 35, 50), \n    tf.image.random_saturation(chosen_image, 5, 10), \n    tf.image.transpose(chosen_image),\n]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_matrix_list = []\nbboxes_list = []\nfor aug_image in tf_trans_list:\n    img_matrix_list.append(aug_image)\n\nimg_matrix_list.insert(0, chosen_image)    \n\ntitles_list = [\"Original\",\"Rotate90\",\"Rotate180\",\"Rotate270\",\"RandomBrightness\",\"RandomContrast\",\"RandomLeftRightFlip\",\"RandomUpDownFlip\",\n               \"RandomHue\",\"RandomJPEGQuality\",\"RandomSaturation\",\"Transpose\"]\n\nplot_multiple_img(img_matrix_list, titles_list, ncols = 3, nrows=4, main_title=\"Different Types of Augmentations with TensorFlow\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"3\"></a>\n<h1 style='color:#0A0502; background:white; border:0'><center>Model preparation</center></h1>\n\n[**Back to the table of contents**](#start)"},{"metadata":{"trusted":true},"cell_type":"code","source":"# main parameters\nAUTO = tf.data.experimental.AUTOTUNE\nBATCH_SIZE = 16 * REPLICAS\nSTEPS_PER_EPOCH = len(train) * 0.8 / BATCH_SIZE\nVALIDATION_STEPS = len(train) * 0.2 / BATCH_SIZE\nEPOCHS = 30\nTARGET_SIZE = 600","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_decoder(with_labels = True,\n                  target_size = (TARGET_SIZE, TARGET_SIZE), \n                  ext = 'jpg'):\n    def decode(path):\n        file_bytes = tf.io.read_file(path)\n        if ext == 'png':\n            img = tf.image.decode_png(file_bytes, channels = 3)\n        elif ext in ['jpg', 'jpeg']:\n            img = tf.image.decode_jpeg(file_bytes, channels = 3)\n        else:\n            raise ValueError(\"Image extension not supported\")\n\n        img = tf.cast(img, tf.float32) / 255.0\n        img = tf.image.resize(img, target_size)\n\n        return img\n    \n    def decode_with_labels(path, label):\n        return decode(path), label\n    \n    return decode_with_labels if with_labels else decode\n\n# in this part you can choose any type of augmentation from the ones suggested above\ndef build_augmenter(with_labels = True):\n    def augment(img):\n        #img = NeedleAugmentation(img, n_needles=2, dark_needles=False, p=0.5)\n        img = tf.image.random_flip_left_right(img)\n        img = tf.image.random_flip_up_down(img)\n        img = tf.image.random_brightness(img, 0.9, 1)\n        img = tf.image.random_contrast(img, 0.9, 1)\n        #img = tf.image.random_saturation(img, 0.9, 1) \n        \n        return img\n    \n    def augment_with_labels(img, label):\n        return augment(img), label\n    \n    return augment_with_labels if with_labels else augment\n\n\ndef build_dataset(paths, labels = None, bsize = 32, cache = True,\n                  decode_fn = None, augment_fn = None,\n                  augment = True, repeat = True, shuffle = 1024, \n                  cache_dir = \"\"):\n    if cache_dir != \"\" and cache is True:\n        os.makedirs(cache_dir, exist_ok=True)\n    \n    if decode_fn is None:\n        decode_fn = build_decoder(labels is not None)\n    \n    if augment_fn is None:\n        augment_fn = build_augmenter(labels is not None)\n    \n    slices = paths if labels is None else (paths, labels)\n    \n    dset = tf.data.Dataset.from_tensor_slices(slices)\n    dset = dset.map(decode_fn, num_parallel_calls = AUTO)\n    dset = dset.cache(cache_dir) if cache else dset\n    dset = dset.map(augment_fn, num_parallel_calls = AUTO) if augment else dset\n    dset = dset.repeat() if repeat else dset\n    dset = dset.shuffle(shuffle) if shuffle else dset\n    dset = dset.batch(bsize).prefetch(AUTO)\n    \n    return dset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train test split\n(train_img, valid_img, \n train_labels, valid_labels) = train_test_split(train_images, labels, \n                                                train_size = 0.8, \n                                                random_state = 42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Tensorflow datasets\ntrain_df = build_dataset(\n    train_img, train_labels, bsize = BATCH_SIZE, \n    cache = True)\n\nvalid_df = build_dataset(\n    valid_img, valid_labels, bsize = BATCH_SIZE, \n    repeat = False, shuffle = False, augment = False, \n    cache = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_model(model):\n    conv_base = model(include_top = False, weights = 'imagenet',\n                         input_shape = (TARGET_SIZE, TARGET_SIZE, 3))\n    model = conv_base.output\n    model = layers.GlobalAveragePooling2D()(model)\n    model = layers.Dense(11, activation = \"sigmoid\")(model)\n    model = models.Model(conv_base.input, model)\n\n    model.compile(optimizer = 'adam',\n                  loss = \"binary_crossentropy\",\n                  metrics = [tf.keras.metrics.AUC(multi_label = True)])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model_EfficientNetB7 = create_model(EfficientNetB7) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#tf.keras.utils.plot_model(model_EfficientNetB7, show_shapes=False)\nprint('EfficientNetB7 CNN has %d layers' %len(model_EfficientNetB7.layers))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_save_EfficientNetB7 = ModelCheckpoint('./EfficientNetB7_best_weights_TPU.h5', \n                             save_best_only = True, \n                             save_weights_only = True,\n                             monitor = 'val_auc', \n                             mode = 'max', verbose = 1)\nearly_stop = EarlyStopping(monitor = 'val_auc', min_delta = 0.0001, \n                           patience = 5, mode = 'max', verbose = 1,\n                           restore_best_weights = True)\nreduce_lr = ReduceLROnPlateau(monitor = 'val_auc', patience = 3, min_lr=1e-6, \n                              mode = 'max', verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"4\"></a>\n<h1 style='color:#0A0502; background:white; border:0'><center>Model training</center></h1>\n\n[**Back to the table of contents**](#start)"},{"metadata":{"trusted":true},"cell_type":"code","source":"history_EfficientNetB7 = model_EfficientNetB7.fit(\n    train_df,\n    epochs = EPOCHS,\n    steps_per_epoch = STEPS_PER_EPOCH,\n    validation_data = valid_df,\n    validation_steps = VALIDATION_STEPS,\n    callbacks = [model_save_EfficientNetB7, early_stop, reduce_lr]\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"auc = history_EfficientNetB7.history['auc']\nval_auc = history_EfficientNetB7.history['val_auc']\nloss = history_EfficientNetB7.history['loss']\nval_loss = history_EfficientNetB7.history['val_loss']\n\nepochs = range(1, len(auc) + 1)\n\nfig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8))\nsns.set_style(\"white\")\nplt.suptitle('Train history for EfficientNetB7 model', size = 15)\n\nax1.plot(epochs, auc, \"bo\", label = \"Training auc\")\nax1.plot(epochs, val_auc, \"b\", label = \"Validation auc\")\nax1.set_title(\"Training and validation auc\")\nax1.legend()\n\nax2.plot(epochs, loss, \"bo\", label = \"Training loss\", color = 'red')\nax2.plot(epochs, val_loss, \"b\", label = \"Validation loss\", color = 'red')\nax2.set_title(\"Training and validation loss\")\nax2.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# save model\nmodel_EfficientNetB7.save('./EfficientNetB7_TPU.h5')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"5\"></a>\n<h1 style='color:#0A0502; background:white; border:0'><center>Visualization of CNN intermediate activations</center></h1>\n\n[**Back to the table of contents**](#start)"},{"metadata":{"trusted":true},"cell_type":"code","source":"def activation_layer_vis(img, activation_layer = 0, layers = 10):\n    layer_outputs = [layer.output for layer in model_EfficientNetB7.layers[:layers]]\n    activation_model = models.Model(inputs = model_EfficientNetB7.input, outputs = layer_outputs)\n    activations = activation_model.predict(img)\n    \n    rows = int(activations[activation_layer].shape[3] / 3)\n    cols = int(activations[activation_layer].shape[3] / rows)\n    fig, axes = plt.subplots(rows, cols, figsize = (15, 15 * cols))\n    axes = axes.flatten()\n    \n    for i, ax in zip(range(activations[activation_layer].shape[3]), axes):\n        ax.matshow(activations[activation_layer][0, :, :, i], cmap = 'viridis')\n        ax.axis('off')\n    plt.tight_layout()\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_tensor = build_dataset(\n    pd.Series(train_img[0]), bsize = 1,repeat = False, \n    shuffle = False, augment = False, cache = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"activation_layer_vis(img_tensor)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def all_activations_vis(img, layers = 10):\n    layer_outputs = [layer.output for layer in model_EfficientNetB7.layers[:layers]]\n    activation_model = models.Model(inputs = model_EfficientNetB7.input, outputs = layer_outputs)\n    activations = activation_model.predict(img)\n    \n    layer_names = []\n    for layer in model_EfficientNetB7.layers[:layers]: \n        layer_names.append(layer.name) \n\n    images_per_row = 3\n    for layer_name, layer_activation in zip(layer_names, activations): \n        n_features = layer_activation.shape[-1] \n\n        size = layer_activation.shape[1] \n\n        n_cols = n_features // images_per_row \n        display_grid = np.zeros((size * n_cols, images_per_row * size)) \n\n        for col in range(n_cols): \n            for row in range(images_per_row): \n                channel_image = layer_activation[0, :, :, col * images_per_row + row] \n                channel_image -= channel_image.mean() \n                channel_image /= channel_image.std() \n                channel_image *= 64 \n                channel_image += 128 \n                channel_image = np.clip(channel_image, 0, 255).astype('uint8') \n                display_grid[col * size : (col + 1) * size, \n                             row * size : (row + 1) * size] = channel_image \n        scale = 1. / size \n        plt.figure(figsize=(scale * 5 * display_grid.shape[1], \n                            scale * 5 * display_grid.shape[0])) \n        plt.title(layer_name) \n        plt.grid(False)\n        plt.axis('off')\n        plt.imshow(display_grid, aspect = 'auto', cmap = 'viridis')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_activations_vis(img_tensor, 3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"6\"></a>\n<h1 style='color:#0A0502; background:white; border:0'><center>Prediction</center></h1>\n\n[**Back to the table of contents**](#start)"},{"metadata":{},"cell_type":"markdown","source":"For submission you need to create a new notebook with GPU and load the pretrained weights from this notebook. "},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = build_dataset(\n    test_images, bsize = BATCH_SIZE, repeat = False, \n    shuffle = False, augment = False, cache = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ss[label_cols] = model_EfficientNetB7.predict(test_df)\nss.to_csv('submission.csv', index = False)\nss.head()","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}