{"cells":[{"metadata":{},"cell_type":"markdown","source":"# PLAN OF ATTACK🎓\n\n<img src=\"https://user-images.githubusercontent.com/64481847/111900431-923a9500-8a58-11eb-9e13-a773c9cf814a.png\" height=\"300\" align=\"left\">"},{"metadata":{},"cell_type":"markdown","source":"\n### Image Embedding Notebook (Part-i)\n\n### TPU in ACTION\n<img src=\"https://bestanimations.com/media/molecular-bonding/37507859alpha-amanitin-molecule-animation.gif\" height=\"400\" align=\"left\">\n\n\n# DATA Processing Pipeline"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\n\nfrom kaggle_datasets import KaggleDatasets\nfrom sklearn.model_selection import train_test_split\n\nimport tensorflow as tf\nimport tensorflow.keras as keras\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, ModelCheckpoint, EarlyStopping","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CONFIG(object):\n  \"\"\"CONFIG\"\"\"\n  def __init__(self):\n    self.img_size = (256,256)\n    self.base= '../input/bms-molecular-translation/'\n    self.df= '../input/bms-molecular-translation/train_labels.csv'\n    self.batch_size= 14\n    self.val_split= 0.1\n    self.seed= 22\n    self.n_epochs= 40\n    \n    \ncfg= CONFIG()\n\ndef load_path(img_id):\n    return img_id[0] +'/'+img_id[1]+'/'+img_id[2] +'/'+img_id+'.png'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df= pd.read_csv(cfg.df)\ndf['path']= df.image_id.apply(load_path)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def load_img(img_id):\n    path= cfg.base+'train/'+ img_id[0] +'/'+img_id[1]+'/'+img_id[2] +'/'+img_id+'.png'\n    img= cv2.imread(path)\n    img= cv2.resize(img, cfg.img_size)\n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_decoder(with_labels=True, target_size=cfg.img_size, ext='png'):\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        img= tf.cast((img> 0.9), tf.float32)\n        return img\n    \n    def decode_with_labels(path):\n        x= decode(path)\n        return x, x\n    \n    return decode_with_labels if with_labels else decode\n\nimg_decoder = build_decoder(with_labels=True, target_size= cfg.img_size,  ext='png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# TPU or GPU detection\ndef auto_select_accelerator():\n    \"\"\"\n    Reference: \n        * https://www.kaggle.com/mgornergoogle/getting-started-with-100-flowers-on-tpu\n        * https://www.kaggle.com/xhlulu/ranzcr-efficientnet-tpu-training\n    \"\"\"\n    try:  # detect TPUs\n        tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  ## detect TPUs\n        tf.config.experimental_connect_to_cluster(tpu)\n        tf.tpu.experimental.initialize_tpu_system(tpu)\n        strategy = tf.distribute.experimental.TPUStrategy(tpu)\n        print(\"Running on TPU:\", tpu.master())\n    except ValueError:\n        strategy = tf.distribute.MirroredStrategy() # for GPU or multi-GPU machines\n        #strategy = tf.distribute.get_strategy() # default strategy that works on CPU and single GPU\n        #strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy() # for clusters of multi-GPU machines\n        \n    print(f\"Running on {strategy.num_replicas_in_sync} replicas\")\n    return strategy","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def Build_dataset(paths, labels= None, batch= cfg.batch_size,\n                  decode_fn=img_decoder,repeat= True, shuffle= cfg.seed):\n    AUTO = tf.data.experimental.AUTOTUNE\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.repeat() if repeat else dset\n    dset = dset.shuffle(shuffle) if shuffle else dset\n    dset = dset.batch(batch).prefetch(AUTO)\n    \n    return dset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DATASET_NAME  = \"bms-org-data\"\nstrategy = auto_select_accelerator()\nBATCH_SIZE = strategy.num_replicas_in_sync * cfg.batch_size\n\ntpu_bsize= cfg.batch_size * strategy.num_replicas_in_sync\ntpu_bsize","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<img src=\"https://electronicsworld.co.uk/wp-content/uploads/2019/10/google-tpu-3-1.jpg\" width=\"400\" align=\"left\">"},{"metadata":{"trusted":true},"cell_type":"code","source":"GCS_DS_PATH = KaggleDatasets().get_gcs_path(DATASET_NAME)\nGCS_DS_PATH","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_paths= GCS_DS_PATH+ '/train/' + pd.Series(os.listdir('../input/bms-org-data/train/'))\n\n# Train test split\n(train_paths, valid_paths)\\\n    = train_test_split(img_paths, test_size=cfg.val_split, random_state=11)\n\nprint(train_paths.shape, valid_paths.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Build the tensorflow datasets\nimg_gen = Build_dataset(train_paths, labels= None, repeat=False, shuffle=False)\n\nval_gen = Build_dataset(valid_paths, labels= None, repeat=False, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data, _ = img_gen.take(2)\nimages = data[0].numpy()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Input Images .............."},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, axes = plt.subplots(3, 4, figsize=(15,10))\naxes = axes.flatten()\nfor img, ax in zip(images, axes):\n    ax.imshow(img, aspect= True)\n    ax.axis('off')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<img src=\"https://www.brown.edu/Departments/Engineering/Labs/Peterson/tips/img/animated/animation.gif\" width=\"400\" align=\"left\">\n\n\n# U-NET Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras import Input\nfrom tensorflow.keras.layers import Conv2D, Dropout, MaxPooling2D, Conv2DTranspose, concatenate, SeparableConv2D","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def unet_model(input_size = (cfg.img_size[0], cfg.img_size[1], 3)):\n    #https://github.com/lhelontra/squeeze-unet/blob/master/squeezeunet.py\n    \n    inp= Input(input_size)\n    #inp= keras.layers.Lambda(lambda x: x/255)(inp)\n    \n    #Contraction path\n    conv_d0= Conv2D(32, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(inp)\n    conv_d0= Dropout(0.4)(conv_d0)\n    conv_d0= SeparableConv2D(32, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_d0)\n    pool_d0=MaxPooling2D()(conv_d0)\n\n    conv_d1= Conv2D(64, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(pool_d0)\n    conv_d1= Dropout(0.3)(conv_d1)\n    conv_d1= SeparableConv2D(64, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_d1)\n    pool_d1=MaxPooling2D()(conv_d1)\n    \n    conv_d2= SeparableConv2D(128, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(pool_d1)\n    conv_d2= Dropout(0.2)(conv_d2)\n    conv_d2= SeparableConv2D(128, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_d2)\n    pool_d2=MaxPooling2D()(conv_d2)\n    \n    conv_d3= SeparableConv2D(256, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(pool_d2)\n    conv_d3= Dropout(0.3)(conv_d3)\n    conv_d3= SeparableConv2D(256, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_d3)\n    pool_d3=MaxPooling2D()(conv_d3)\n    \n    conv_d4= SeparableConv2D(512, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(pool_d3)\n    conv_d4= Dropout(0.2)(conv_d4)\n    conv_d4= SeparableConv2D(512, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_d4)\n    pool_d4=MaxPooling2D()(conv_d4)\n    \n    conv_d5= SeparableConv2D(1024, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(pool_d4)\n    conv_d5= Dropout(0.3)(conv_d5)\n    conv_d5= SeparableConv2D(1024, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_d5)\n    \n    \n    \n    #Expansive path \n    conv_u4= Conv2DTranspose(512, (2, 2), strides=(2, 2), padding='same')(conv_d5)\n    conv_u4= concatenate([conv_u4,conv_d4])\n    conv_u4= Conv2D(512, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u4)\n    conv_u4= Dropout(0.2)(conv_u4)\n    conv_u4= Conv2D(512, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u4)\n    \n    conv_u3= Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(conv_u4)\n    conv_u3= concatenate([conv_u3,conv_d3])\n    conv_u3= Conv2D(256, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u3)\n    conv_u3= Dropout(0.4)(conv_u3)\n    conv_u3= Conv2D(256, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u3)\n    \n    conv_u2= Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(conv_u3)\n    conv_u2= concatenate([conv_u2,conv_d2])\n    conv_u2= Conv2D(128, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u2)\n    conv_u2= Dropout(0.3)(conv_u2)\n    conv_u2= Conv2D(128, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u2)\n    \n    conv_u1= Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(conv_u2)\n    conv_u1= concatenate([conv_u1,conv_d1])\n    conv_u1= Conv2D(64, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u1)\n    conv_u1= Dropout(0.3)(conv_u1)\n    conv_u1= Conv2D(64, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u1)\n\n    conv_u0= Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same')(conv_u1)\n    conv_u0= concatenate([conv_u0,conv_d0])\n    conv_u0= Conv2D(32, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u0)\n    conv_u0= Dropout(0.3)(conv_u0)\n    conv_u0= Conv2D(32, (3,3), activation='relu', padding='same', kernel_initializer='he_normal')(conv_u0)\n    \n    out=Conv2D(3, (1,1), activation='sigmoid')(conv_u0)\n    \n    return keras.Model(inputs=inp, outputs=out)\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model=unet_model()\n    model.compile(optimizer='adam',\n      loss=tf.keras.losses.BinaryCrossentropy(label_smoothing=0.001),\n      metrics=['accuracy'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#callbacks\nrlr = ReduceLROnPlateau(monitor = 'val_loss', factor = 0.1, patience = 3, verbose = 1, \n                                min_delta = 1e-4, min_lr = 1e-6, mode = 'min', cooldown=1)\n        \nckp = ModelCheckpoint('Unet_model.h5', monitor = 'val_loss',\n                      verbose = 1, save_best_only = True, mode = 'min')\n        \nes = EarlyStopping(monitor = 'val_loss', min_delta = 1e-4, patience = 7, mode = 'min', \n                    restore_best_weights = True, verbose = 1)\n\nsteps_per_epoch = (train_paths.shape[0] // cfg.batch_size)/10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(img_gen,                      \n                    validation_data=val_gen,                                       \n                    epochs=15,\n                    callbacks=[rlr,es,ckp],\n                    steps_per_epoch=steps_per_epoch,\n                    verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize = (12, 6))\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.plot( history.history[\"loss\"], label = \"Training Loss\", marker='o')\nplt.plot( history.history[\"val_loss\"], label = \"Validation Loss\", marker='+')\nplt.grid(True)\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"### Predicted Images ..........."},{"metadata":{"trusted":true},"cell_type":"code","source":"pred= model.predict(images)\n\nfig, axes = plt.subplots(3, 4, figsize=(15,10))\naxes = axes.flatten()\nfor img, ax in zip(pred, axes):\n    ax.imshow(img, aspect= True)\n    ax.axis('off')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"![](https://i.gifer.com/7ImI.gif)\n\n### To be continued for next part............"}],"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}