{"cells":[{"metadata":{"_uuid":"4dda46501b85713c30396f36eced1948e6cdc77d","trusted":true},"cell_type":"code","source":"# Libraries\nimport os, sys, math\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport cv2\nfrom imgaug import augmenters as iaa\nfrom tqdm import tqdm\nfrom tqdm import tqdm_notebook\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"40239b9682631d9f3660b394e3c1025c312a47d4","trusted":true},"cell_type":"code","source":"# Input shape and Batch size for InceptionResNetV2\nINPUT_SHAPE = (299,299,3)\nBATCH_SIZE = 10","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dfafb2ecb394f7507aa244aa6673e78ebfb41d6b","trusted":true},"cell_type":"code","source":"# Name Label Dictionary\nname_label_dict = {\n0:  \"Nucleoplasm\", \n1:  \"Nuclear membrane\",   \n2:  \"Nucleoli\",   \n3:  \"Nucleoli fibrillar center\" ,  \n4:  \"Nuclear speckles\"   ,\n5:  \"Nuclear bodies\"   ,\n6:  \"Endoplasmic reticulum\",   \n7:  \"Golgi apparatus\"   ,\n8:  \"Peroxisomes\"   ,\n9:  \"Endosomes\"   ,\n10:  \"Lysosomes\"   ,\n11:  \"Intermediate filaments\",   \n12:  \"Actin filaments\"   ,\n13:  \"Focal adhesion sites\",   \n14:  \"Microtubules\"   ,\n15:  \"Microtubule ends\",   \n16:  \"Cytokinetic bridge\",   \n17:  \"Mitotic spindle\"   ,\n18:  \"Microtubule organizing center\" ,  \n19:  \"Centrosome\"   ,\n20:  \"Lipid droplets\",   \n21:  \"Plasma membrane\",   \n22:  \"Cell junctions\"  , \n23:  \"Mitochondria\"   ,\n24:  \"Aggresome\"   ,\n25:  \"Cytosol\",\n26:  \"Cytoplasmic bodies\",   \n27:  \"Rods & rings\" \n}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"731e0bfa9d5ebbaeeb6ec4a1a4b0238a23b56b9c","trusted":true},"cell_type":"code","source":"#Load Train Dataset \npath_to_train = '/kaggle/input/train/'\ndata = pd.read_csv('/kaggle/input/train.csv')\n\ntrain_dataset_info = []\nfor name, labels in zip(data['Id'], data['Target'].str.split(' ')):\n    train_dataset_info.append({\n        'path':os.path.join(path_to_train, name),\n        'labels':np.array([int(label) for label in labels])})\ntrain_dataset_info = np.array(train_dataset_info)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"aff85cf5458546208b57557c2ee10362ef17ba0f","trusted":true},"cell_type":"code","source":"# Split Training Data set (80:20)\nfrom sklearn.model_selection import train_test_split\ntrain_ids, test_ids, train_targets, test_target = train_test_split(\n    data['Id'], data['Target'], test_size=0.2, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"835642ecec16760891fd21f784c55a3581b41251","trusted":true},"cell_type":"code","source":"# Create train dataset\ndef create_train(dataset_info, batch_size, shape, augument=True):\n    assert shape[2] == 3\n    while True:\n        random_indexes = np.random.choice(len(dataset_info), batch_size)\n        batch_images = np.empty((batch_size, shape[0], shape[1], shape[2]))\n        batch_labels = np.zeros((batch_size, 28))\n        for i, idx in enumerate(random_indexes):\n            image = load_image(\n                dataset_info[idx]['path'], shape)   \n            if augument:\n                image = augment(image)\n            batch_images[i] = image\n            batch_labels[i][dataset_info[idx]['labels']] = 1\n        yield batch_images, batch_labels\n            \n # Load all the images    \ndef load_image(path, shape):\n    R = np.array(Image.open(path+'_red.png'))\n    G = np.array(Image.open(path+'_green.png'))\n    B = np.array(Image.open(path+'_blue.png'))\n    Y = np.array(Image.open(path+'_yellow.png'))\n\n    image = np.stack((\n        R/2 + Y/2, \n        G/2 + Y/2, \n        B),-1)\n\n    image = cv2.resize(image, (shape[0], shape[1]))\n    image = np.divide(image, 255)\n    return image  \n                \n# augmentation            \ndef augment(image):\n    augment_img = iaa.Sequential([\n        iaa.OneOf([\n            iaa.Affine(rotate=0),\n            iaa.Affine(rotate=90),\n            iaa.Affine(rotate=180),\n            iaa.Affine(rotate=270),\n            iaa.Fliplr(0.5),\n            iaa.Flipud(0.5),\n        ])], random_order=True)\n\n    image_aug = augment_img.augment_image(image)\n    return image_aug","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f469e5b0ccfc03a24bc6ee0d864dc63588b65120","trusted":true},"cell_type":"code","source":"# create train datagen with augmentation\ntrain_datagen = create_train(train_dataset_info, 5, INPUT_SHAPE, augument=True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"601082aaa4474bff3fbb5d753bba42489ee0963f","trusted":true},"cell_type":"code","source":"# Show 5 images with title, just for the refernce\nimages, labels = next(train_datagen)\nfig, (m_axs) = plt.subplots(1, 5, figsize = (25, 10))\nfor i, c_ax in enumerate(m_axs.flatten()):\n    c_ax.imshow(((images[i]-images.min())/(images.max()-images.min()))[:, ::1])\n    c_title = '\\n'.join([name_label_dict[j] for j, v in enumerate(labels[i]) if v>0.5])\n    c_ax.set_title(c_title)\n    c_ax.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"20907c99c26f394e14c6c693a0f65b3b7e3a03ef","trusted":true},"cell_type":"code","source":"# Histroy Plot with loss and accuracy\ndef show_history(history):\n    fig, ax = plt.subplots(1, 2, figsize=(15,5))\n    ax[0].set_title('loss')\n    ax[0].plot(history.epoch, history.history[\"loss\"], label=\"Train loss\")\n    ax[0].plot(history.epoch, history.history[\"val_loss\"], label=\"Validation loss\")\n    ax[1].set_title('acc')\n    ax[1].plot(history.epoch, history.history[\"acc\"], label=\"Train acc\")\n    ax[1].plot(history.epoch, history.history[\"val_acc\"], label=\"Validation acc\")\n    ax[0].legend()\n    ax[1].legend()\n    ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c1bf8afe7c8e1da4153d2dd9d420a9271f36fbbd","trusted":true},"cell_type":"code","source":"# Load Keras Library\nimport tensorflow as tf\nimport keras\nfrom keras import models\nfrom keras import layers\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, load_model\nfrom keras.layers import Activation\nfrom keras.layers import Dropout\nfrom keras.layers import Flatten\nfrom keras.layers import Dense\nfrom keras.layers import Input\nfrom keras.layers import BatchNormalization\nfrom keras.layers import Conv2D\nfrom keras.models import Model\nfrom keras.applications import InceptionResNetV2\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.callbacks import LambdaCallback\nfrom keras.callbacks import Callback\nfrom keras import metrics\nfrom keras.optimizers import Adam \nfrom keras import backend as K","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"dd8ea3a4a21290912902c8da34e2b726c1367acb","trusted":true},"cell_type":"code","source":"#Experiment 1: Freezing all layers - Same as Transfer Learning\n#Load the InceptionResNetV2 model\n\nbase_model = InceptionResNetV2(\n    include_top=False, \n    weights='imagenet', \n    input_shape=INPUT_SHAPE)    \n\n\n# Freeze all the layers\nfor layer in base_model.layers[:]:\n    layer.trainable = False\n\n# Create the model\nmodel = models.Sequential()\n\n# Add the InceptionResNetV2 convolutional base model\nmodel.add(base_model)\n\n# Add new layers\nmodel.add(Conv2D(128, kernel_size=(1,1), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(layers.Flatten())\nmodel.add(Dropout(0.5))\nmodel.add(layers.Dense(1024, activation='relu'))\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(28, activation='sigmoid'))\n\n# Show a summary of the model. Check the number of trainable parameters\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e15d2fb12a75584a369f65c05cf81c3af27eded8","trusted":true},"cell_type":"code","source":"#Experiment 1 : Train the model - No Data augmentation\n\ntrain_generator = create_train(train_dataset_info[train_ids.index], BATCH_SIZE, INPUT_SHAPE, augument=False)\nvalidation_generator = create_train(train_dataset_info[test_ids.index], 256, INPUT_SHAPE, augument=False)\n\ncheckpointer = ModelCheckpoint(\n    '/kaggle/working/InceptionResNetV2.model',\n    verbose=2, save_best_only=True)\n\nmodel.compile(\n    loss='binary_crossentropy',  \n    optimizer=Adam(1e-3),\n    metrics=['acc'])\n\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=100,\n    validation_data=next(validation_generator),\n    epochs=20, \n    verbose=1,\n    callbacks=[checkpointer])\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"413813faf32bd8e117b4ba9c848853b230d77cbf","scrolled":true,"trusted":true},"cell_type":"code","source":"show_history(history)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fdb7a5ae8477f27f21ca51f03d627e3c24e90b00","trusted":true},"cell_type":"code","source":"#Experiment 2 : Train Last 4 layers without data augmentation\n\nbase_model = InceptionResNetV2(\n    include_top=False, \n    weights='imagenet', \n    input_shape=INPUT_SHAPE)    \n\n# Freeze layers\nfor layer in base_model.layers[:-4]:\n    layer.trainable = False\n\n    # Create the model\nmodel = models.Sequential()\n\n# Add the vgg convolutional base model\nmodel.add(base_model)\n\n# Add new layers\nmodel.add(Conv2D(128, kernel_size=(1,1), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(layers.Flatten())\nmodel.add(Dropout(0.5))\nmodel.add(layers.Dense(1024, activation='relu'))\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(28, activation='sigmoid'))\n\n# Show a summary of the model. Check the number of trainable parameters\nmodel.summary()\n        ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"de5c468392ed7cc04a56acdc8a6f3d4000ce9f14","trusted":true},"cell_type":"code","source":"#Experiment 2 : Train the model - no augmentation\n\ntrain_generator = create_train(train_dataset_info[train_ids.index], BATCH_SIZE, INPUT_SHAPE, augument=False)\nvalidation_generator = create_train(train_dataset_info[test_ids.index], 256, INPUT_SHAPE, augument=False)\n\n\nmodel.compile(\n    loss='binary_crossentropy',  \n    optimizer=Adam(1e-4),\n    metrics=['acc'])\n\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=100,\n    validation_data=next(validation_generator),\n    epochs=20, \n    verbose=1,\n    callbacks=[checkpointer])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"47f53f00b6a3864e847f3802e826860ab14f1698","trusted":true},"cell_type":"code","source":"show_history(history)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3405e73a0823c8fdfae351b10193a774c8d8fa29","trusted":true},"cell_type":"code","source":"# Experiment 3 : Train last 4 layers with data augmentation\n\nbase_model = InceptionResNetV2(\n    include_top=False, \n    weights='imagenet', \n    input_shape=INPUT_SHAPE)    \n\n# Freeze all the layers\nfor layer in base_model.layers[:-4]:\n    layer.trainable = False\n    # Create the model\nmodel = models.Sequential()\n\n# Add the vgg convolutional base model\nmodel.add(base_model)\n\n# Add new layers\nmodel.add(Conv2D(128, kernel_size=(1,1), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(layers.Flatten())\nmodel.add(Dropout(0.5))\nmodel.add(layers.Dense(1024, activation='relu'))\nmodel.add(layers.Dropout(0.5))\nmodel.add(layers.Dense(28, activation='sigmoid'))\n\n# Show a summary of the model. Check the number of trainable parameters\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"cca4dabef364eed29f893f370640cc1f12ffd400","trusted":true},"cell_type":"code","source":"#Experiment 3 - Train the model - with augmentation\n\ncheckpointer = ModelCheckpoint(\n    '/kaggle/working/InceptionResNetV2.model',\n    verbose=2, save_best_only=True)\n\ntrain_generator = create_train(train_dataset_info[train_ids.index], BATCH_SIZE, INPUT_SHAPE, augument=True)\nvalidation_generator = create_train(train_dataset_info[test_ids.index], 256, INPUT_SHAPE, augument=False)\n\nmodel.compile(\n    loss='binary_crossentropy',  \n    optimizer=Adam(1e-4),\n    metrics=['acc'])\n\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=100,\n    validation_data=next(validation_generator),\n    epochs=20, \n    verbose=1,\n    callbacks=[checkpointer])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"41892ed4f6e1afd1ed8aafcb2a6ef904befe5553","trusted":true},"cell_type":"code","source":"show_history(history)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2e3df2223d44b2f4962adcf6e789b784d1280e19","trusted":true},"cell_type":"code","source":"# Prediction test Dir\ntest_csv = pd.read_csv(\"../input/sample_submission.csv\")\ntest_csv.head()\n\n# Testing images path\nTEST_PATH = \"../input/test/\"\nids_test = test_csv[\"Id\"]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0da93e997b55e68c25bf7a29ec8feee9539b1c87","trusted":true},"cell_type":"code","source":"predicted = []\nfor name in tqdm(test_csv['Id']):\n    path = os.path.join('../input/test/', name)\n    image = load_image(path, INPUT_SHAPE)\n    score_predict = model.predict(image[np.newaxis])[0]\n    label_predict = np.arange(28)[score_predict>=0.2]\n    str_predict_label = ' '.join(str(l) for l in label_predict)\n    predicted.append(str_predict_label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f68cec07ef9a9c067bcad17ff51ec1c76695f221"},"cell_type":"code","source":"test_csv['Predicted'] = predicted","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9cacbb626d78ab373eaae782ca841d52ef86a9ae","scrolled":true,"trusted":true},"cell_type":"code","source":"# Prepare submission file\ntest_csv['Predicted'].value_counts()[:20]\nout_df = test_csv[['Id', 'Predicted']]\nout_df = out_df[out_df.Predicted != '']\ntest_csv.to_csv('sample_submission.csv', index=False)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"67e28768c620742750a2bc43b1add73887765aa2"},"cell_type":"code","source":"path_to_test = '/kaggle/input/test/'\n#out_df['Predicted']=out_df['Predicted'].astype(str)\ntest_dataset_info = []    \nfor name, labels in zip(out_df['Id'], out_df['Predicted'].str.split(' ')):\n    test_dataset_info.append({\n        'path':os.path.join(path_to_test, name),\n        'labels':np.array([int(label) for label in labels])})\ntest_dataset_info = np.array(test_dataset_info)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f222a4629817f3fad45597e7d5cbc040e36f054e"},"cell_type":"code","source":"# create test datagen with augmentation\ntest_datagen = create_train(test_dataset_info, 5, INPUT_SHAPE, augument=True)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b4a5a9768eb43a375636bc1ebe366121b53ce7c4"},"cell_type":"code","source":"# Show 5 predicted images with title and prediction\nimages, labels = next(test_datagen)\npredict_test = model.predict(images)\nfig, (m_axs) = plt.subplots(1, 5, figsize = (25, 10))\nfor i, c_ax in enumerate(m_axs.flatten()):\n    c_ax.imshow(((images[i]-images.min())/(images.max()-images.min()))[:, ::1])\n    c_title = '\\n'.join(['{}: Pred: {:2.1f}%'.format(name_label_dict[j], 100*predict_test[i, j]) \n                         for j, v in enumerate(labels[i]) if v>0.5])\n   \n    c_ax.set_title(c_title)\n    c_ax.axis('off')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}