{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":11848,"databundleVersionId":862157,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import Packages","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport os\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nfrom sklearn.model_selection import train_test_split\nimport pickle\n\nimport tensorflow as tf\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.models import Sequential, load_model\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom tensorflow.keras import backend as K","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:04:43.403553Z","iopub.execute_input":"2024-08-09T01:04:43.404315Z","iopub.status.idle":"2024-08-09T01:04:56.230698Z","shell.execute_reply.started":"2024-08-09T01:04:43.404280Z","shell.execute_reply":"2024-08-09T01:04:56.229715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helper Functions","metadata":{}},{"cell_type":"code","source":"def merge_history(hlist):\n    history = {}\n    for k in hlist[0].history.keys():\n        history[k] = sum([h.history[k] for h in hlist], [])\n    return history\n\ndef vis_training(h, start=1):\n    epoch_range = range(start, len(h['loss'])+1)\n    s = slice(start-1, None)\n\n    plt.figure(figsize=[14,4])\n\n    n = int(len(h.keys()) / 2)\n\n    for i in range(n):\n        k = list(h.keys())[i]\n        plt.subplot(1,n,i+1)\n        plt.plot(epoch_range, h[k][s], label='Training')\n        plt.plot(epoch_range, h['val_' + k][s], label='Validation')\n        plt.xlabel('Epoch'); plt.ylabel(k); plt.title(k)\n        plt.grid()\n        plt.legend()\n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:04:56.232774Z","iopub.execute_input":"2024-08-09T01:04:56.233896Z","iopub.status.idle":"2024-08-09T01:04:56.243840Z","shell.execute_reply.started":"2024-08-09T01:04:56.233859Z","shell.execute_reply":"2024-08-09T01:04:56.242897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Training DataFrames ","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/histopathologic-cancer-detection/train_labels.csv', dtype=str)\ntrain_path = ('/kaggle/input/histopathologic-cancer-detection/train/')","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:04:56.244957Z","iopub.execute_input":"2024-08-09T01:04:56.245358Z","iopub.status.idle":"2024-08-09T01:04:56.602309Z","shell.execute_reply.started":"2024-08-09T01:04:56.245330Z","shell.execute_reply":"2024-08-09T01:04:56.601516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, valid_df = train_test_split(train, test_size=0.2, stratify=train['label'], random_state=1)\nprint(train_df.shape)\nprint(valid_df.shape)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:04:56.604266Z","iopub.execute_input":"2024-08-09T01:04:56.604569Z","iopub.status.idle":"2024-08-09T01:04:56.930297Z","shell.execute_reply.started":"2024-08-09T01:04:56.604543Z","shell.execute_reply":"2024-08-09T01:04:56.929234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n    rescale=1./255,\n    horizontal_flip=True,\n    rotation_range=90\n)\nvalid_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n    rescale=1./255,\n    horizontal_flip=True,\n    rotation_range=90\n)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:04:56.931865Z","iopub.execute_input":"2024-08-09T01:04:56.932179Z","iopub.status.idle":"2024-08-09T01:04:56.937669Z","shell.execute_reply.started":"2024-08-09T01:04:56.932153Z","shell.execute_reply":"2024-08-09T01:04:56.936670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 256\n\ntrain_df['id'] += '.tif'\nvalid_df['id'] += '.tif'\n\ntrain_loader = train_datagen.flow_from_dataframe(\n    dataframe = train_df,\n    directory = train_path,\n    x_col = 'id',\n    y_col = 'label',\n    batch_size = BATCH_SIZE,\n    seed = 1,\n    shuffle = True,\n    class_mode = 'binary',\n    target_size = (96,96)\n)\n\nvalid_loader = train_datagen.flow_from_dataframe(\n    dataframe = valid_df,\n    directory = train_path,\n    x_col = 'id',\n    y_col = 'label',\n    batch_size = BATCH_SIZE,\n    seed = 1,\n    shuffle = True,\n    class_mode = 'binary',\n    target_size = (96,96)\n)\n   ","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:04:56.938925Z","iopub.execute_input":"2024-08-09T01:04:56.939654Z","iopub.status.idle":"2024-08-09T01:11:03.826906Z","shell.execute_reply.started":"2024-08-09T01:04:56.939628Z","shell.execute_reply":"2024-08-09T01:11:03.826053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TR_STEPS = len(train_loader)//BATCH_SIZE\nVA_STEPS = len(valid_loader)//BATCH_SIZE\n\nprint(TR_STEPS)\nprint(VA_STEPS)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:11:03.828277Z","iopub.execute_input":"2024-08-09T01:11:03.828643Z","iopub.status.idle":"2024-08-09T01:11:03.834199Z","shell.execute_reply.started":"2024-08-09T01:11:03.828610Z","shell.execute_reply":"2024-08-09T01:11:03.833370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model 1- Transfer Learning with MobileNetV2","metadata":{}},{"cell_type":"code","source":"base_model1 = tf.keras.applications.MobileNetV2(\n    weights='imagenet',\n    input_shape=(96,96,3),\n    include_top=False,\n)\n\nbase_model1.trainable = False\n\ninputs = tf.keras.Input(shape=(96,96,3))\n\nx = base_model1(inputs)\n  \nx = tf.keras.layers.GlobalAveragePooling2D()(x)\nx = tf.keras.layers.Dense(128, activation= 'relu')(x)\nx = tf.keras.layers.Dropout(0.50)(x)\nx = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n\noutputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n\nmodel1 = tf.keras.Model(inputs, x)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:13:17.401473Z","iopub.execute_input":"2024-08-09T01:13:17.401884Z","iopub.status.idle":"2024-08-09T01:13:19.653693Z","shell.execute_reply.started":"2024-08-09T01:13:17.401841Z","shell.execute_reply":"2024-08-09T01:13:19.652961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train Network","metadata":{}},{"cell_type":"code","source":"opt = tf.keras.optimizers.Adam(learning_rate=0.007)\n\nmodel1.compile(optimizer=opt,\n              loss=tf.keras.losses.BinaryCrossentropy(),\n              metrics=[tf.keras.metrics.AUC()])","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:13:27.830276Z","iopub.execute_input":"2024-08-09T01:13:27.830936Z","iopub.status.idle":"2024-08-09T01:13:27.854543Z","shell.execute_reply.started":"2024-08-09T01:13:27.830903Z","shell.execute_reply":"2024-08-09T01:13:27.853792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1.summary()\n","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:13:31.981303Z","iopub.execute_input":"2024-08-09T01:13:31.981912Z","iopub.status.idle":"2024-08-09T01:13:32.013561Z","shell.execute_reply.started":"2024-08-09T01:13:31.981879Z","shell.execute_reply":"2024-08-09T01:13:32.012767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.random.seed(1)\ntf.random.set_seed(1)\n\n\nh1 = model1.fit(\nx = train_loader, \nsteps_per_epoch = TR_STEPS, \nepochs = 25, \nvalidation_data = valid_loader, \nvalidation_steps = VA_STEPS, \nverbose = 1\n)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T01:13:41.300723Z","iopub.execute_input":"2024-08-09T01:13:41.301123Z","iopub.status.idle":"2024-08-09T02:19:13.642912Z","shell.execute_reply.started":"2024-08-09T01:13:41.301095Z","shell.execute_reply":"2024-08-09T02:19:13.641974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = merge_history([h1])\nvis_training(history)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T02:19:51.809723Z","iopub.execute_input":"2024-08-09T02:19:51.810607Z","iopub.status.idle":"2024-08-09T02:19:52.354139Z","shell.execute_reply.started":"2024-08-09T02:19:51.810575Z","shell.execute_reply":"2024-08-09T02:19:52.353224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model1.trainable = True\nfor layer in base_model1.layers[:-20]:\n    layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2024-08-09T02:20:13.249557Z","iopub.execute_input":"2024-08-09T02:20:13.250177Z","iopub.status.idle":"2024-08-09T02:20:13.261717Z","shell.execute_reply.started":"2024-08-09T02:20:13.250144Z","shell.execute_reply":"2024-08-09T02:20:13.260795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = tf.keras.optimizers.Adam(learning_rate=0.000001)\n\nmodel1.compile(optimizer=opt,\n              loss=tf.keras.losses.BinaryCrossentropy(),\n              metrics=[tf.keras.metrics.AUC()])","metadata":{"execution":{"iopub.status.busy":"2024-08-09T02:20:18.032547Z","iopub.execute_input":"2024-08-09T02:20:18.033215Z","iopub.status.idle":"2024-08-09T02:20:18.055267Z","shell.execute_reply.started":"2024-08-09T02:20:18.033184Z","shell.execute_reply":"2024-08-09T02:20:18.054392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1.summary()","metadata":{"execution":{"iopub.status.busy":"2024-08-09T02:20:20.462801Z","iopub.execute_input":"2024-08-09T02:20:20.463602Z","iopub.status.idle":"2024-08-09T02:20:20.496348Z","shell.execute_reply.started":"2024-08-09T02:20:20.463571Z","shell.execute_reply":"2024-08-09T02:20:20.495501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.random.seed(1)\ntf.random.set_seed(1)\n\nh2 = model1.fit(\nx = train_loader, \nsteps_per_epoch = TR_STEPS, \nepochs = 30, \nvalidation_data = valid_loader, \nvalidation_steps = VA_STEPS, \nverbose = 1\n)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T02:20:24.432082Z","iopub.execute_input":"2024-08-09T02:20:24.432415Z","iopub.status.idle":"2024-08-09T03:33:31.909549Z","shell.execute_reply.started":"2024-08-09T02:20:24.432390Z","shell.execute_reply":"2024-08-09T03:33:31.908743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = merge_history([h2])\nvis_training(history)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T03:34:24.934512Z","iopub.execute_input":"2024-08-09T03:34:24.935467Z","iopub.status.idle":"2024-08-09T03:34:25.525311Z","shell.execute_reply.started":"2024-08-09T03:34:24.935424Z","shell.execute_reply":"2024-08-09T03:34:25.524427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model 2-Transfer Learning with ResNet50","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50\n\nbase_model2 = tf.keras.applications.ResNet50(\n    weights='imagenet',\n    input_shape=(96,96,3),\n    include_top=False,\n)\n\nbase_model2.trainable = False\n\ninputs = tf.keras.Input(shape=(96,96,3))\n\nx = base_model2(inputs)\n  \nx = tf.keras.layers.GlobalAveragePooling2D()(x)\nx = tf.keras.layers.Dense(128, activation= 'relu')(x)\nx = tf.keras.layers.Dropout(0.25)(x)\nx = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n\noutput = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n\nmodel2 = tf.keras.Model(inputs, x)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T03:38:47.028988Z","iopub.execute_input":"2024-08-09T03:38:47.029361Z","iopub.status.idle":"2024-08-09T03:38:48.553985Z","shell.execute_reply.started":"2024-08-09T03:38:47.029330Z","shell.execute_reply":"2024-08-09T03:38:48.552632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = tf.keras.optimizers.Adam(learning_rate=0.007)\nmodel2.compile(optimizer=opt,\n              loss=tf.keras.losses.BinaryCrossentropy(),\n              metrics=[tf.keras.metrics.AUC()])","metadata":{"execution":{"iopub.status.busy":"2024-08-09T03:38:53.920824Z","iopub.execute_input":"2024-08-09T03:38:53.921454Z","iopub.status.idle":"2024-08-09T03:38:53.944283Z","shell.execute_reply.started":"2024-08-09T03:38:53.921425Z","shell.execute_reply":"2024-08-09T03:38:53.943391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model2.summary()","metadata":{"execution":{"iopub.status.busy":"2024-08-09T03:38:59.018657Z","iopub.execute_input":"2024-08-09T03:38:59.019291Z","iopub.status.idle":"2024-08-09T03:38:59.049952Z","shell.execute_reply.started":"2024-08-09T03:38:59.019261Z","shell.execute_reply":"2024-08-09T03:38:59.049006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.random.seed(1)\ntf.random.set_seed(1)\n\nh3 = model2.fit(\nx = train_loader, \nsteps_per_epoch = TR_STEPS, \nepochs = 25, \nvalidation_data = valid_loader, \nvalidation_steps = VA_STEPS, \nverbose = 1\n)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T03:39:03.154611Z","iopub.execute_input":"2024-08-09T03:39:03.155281Z","iopub.status.idle":"2024-08-09T04:40:52.306174Z","shell.execute_reply.started":"2024-08-09T03:39:03.155248Z","shell.execute_reply":"2024-08-09T04:40:52.305326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = merge_history([h3])\nvis_training(history)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T04:40:52.308053Z","iopub.execute_input":"2024-08-09T04:40:52.308350Z","iopub.status.idle":"2024-08-09T04:40:52.939703Z","shell.execute_reply.started":"2024-08-09T04:40:52.308325Z","shell.execute_reply":"2024-08-09T04:40:52.938639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model2.trainable = True\nfor layer in base_model2.layers[:-20]:\n    layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2024-08-09T04:41:22.191561Z","iopub.execute_input":"2024-08-09T04:41:22.191970Z","iopub.status.idle":"2024-08-09T04:41:22.204943Z","shell.execute_reply.started":"2024-08-09T04:41:22.191937Z","shell.execute_reply":"2024-08-09T04:41:22.203825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = tf.keras.optimizers.Adam(learning_rate=0.000001)\n\nmodel2.compile(optimizer=opt,\n              loss=tf.keras.losses.BinaryCrossentropy(),\n              metrics=[tf.keras.metrics.AUC()])","metadata":{"execution":{"iopub.status.busy":"2024-08-09T04:41:28.302892Z","iopub.execute_input":"2024-08-09T04:41:28.303234Z","iopub.status.idle":"2024-08-09T04:41:28.327462Z","shell.execute_reply.started":"2024-08-09T04:41:28.303210Z","shell.execute_reply":"2024-08-09T04:41:28.326508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model2.summary()","metadata":{"execution":{"iopub.status.busy":"2024-08-09T04:41:30.293181Z","iopub.execute_input":"2024-08-09T04:41:30.293882Z","iopub.status.idle":"2024-08-09T04:41:30.324556Z","shell.execute_reply.started":"2024-08-09T04:41:30.293850Z","shell.execute_reply":"2024-08-09T04:41:30.323656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.random.seed(1)\ntf.random.set_seed(1)\n\nh4 = model2.fit(\nx = train_loader, \nsteps_per_epoch = TR_STEPS, \nepochs = 30, \nvalidation_data = valid_loader, \nvalidation_steps = VA_STEPS, \nverbose = 1\n)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T04:41:35.758010Z","iopub.execute_input":"2024-08-09T04:41:35.758729Z","iopub.status.idle":"2024-08-09T05:55:52.250579Z","shell.execute_reply.started":"2024-08-09T04:41:35.758697Z","shell.execute_reply":"2024-08-09T05:55:52.249788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = merge_history([h4])\nvis_training(history)","metadata":{"execution":{"iopub.status.busy":"2024-08-09T05:55:52.252263Z","iopub.execute_input":"2024-08-09T05:55:52.252554Z","iopub.status.idle":"2024-08-09T05:55:52.752789Z","shell.execute_reply.started":"2024-08-09T05:55:52.252523Z","shell.execute_reply":"2024-08-09T05:55:52.751789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1.save('Histopath_model_v13.h5')\npickle.dump(history, open(f'Histopath_history_v13.pk1', 'wb'))","metadata":{"execution":{"iopub.status.busy":"2024-08-09T05:58:26.725825Z","iopub.execute_input":"2024-08-09T05:58:26.726680Z","iopub.status.idle":"2024-08-09T05:58:27.077613Z","shell.execute_reply.started":"2024-08-09T05:58:26.726647Z","shell.execute_reply":"2024-08-09T05:58:27.076801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}