{"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-04T23:18:51.114971Z","iopub.execute_input":"2024-08-04T23:18:51.115365Z","iopub.status.idle":"2024-08-04T23:19:04.282085Z","shell.execute_reply.started":"2024-08-04T23:18:51.115332Z","shell.execute_reply":"2024-08-04T23:19:04.281040Z"},"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-04T23:19:04.283842Z","iopub.execute_input":"2024-08-04T23:19:04.284391Z","iopub.status.idle":"2024-08-04T23:19:04.293653Z","shell.execute_reply.started":"2024-08-04T23:19:04.284364Z","shell.execute_reply":"2024-08-04T23:19:04.292610Z"},"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-04T23:19:04.294921Z","iopub.execute_input":"2024-08-04T23:19:04.295200Z","iopub.status.idle":"2024-08-04T23:19:04.643191Z","shell.execute_reply.started":"2024-08-04T23:19:04.295176Z","shell.execute_reply":"2024-08-04T23:19:04.642372Z"},"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-04T23:19:04.645385Z","iopub.execute_input":"2024-08-04T23:19:04.645679Z","iopub.status.idle":"2024-08-04T23:19:04.976483Z","shell.execute_reply.started":"2024-08-04T23:19:04.645654Z","shell.execute_reply":"2024-08-04T23:19:04.975546Z"},"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-04T23:19:04.977632Z","iopub.execute_input":"2024-08-04T23:19:04.977914Z","iopub.status.idle":"2024-08-04T23:19:04.984771Z","shell.execute_reply.started":"2024-08-04T23:19:04.977891Z","shell.execute_reply":"2024-08-04T23:19:04.983755Z"},"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-04T23:19:04.985941Z","iopub.execute_input":"2024-08-04T23:19:04.986220Z","iopub.status.idle":"2024-08-04T23:24:13.391088Z","shell.execute_reply.started":"2024-08-04T23:19:04.986197Z","shell.execute_reply":"2024-08-04T23:24:13.390289Z"},"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-04T23:24:13.392732Z","iopub.execute_input":"2024-08-04T23:24:13.393090Z","iopub.status.idle":"2024-08-04T23:24:13.398489Z","shell.execute_reply.started":"2024-08-04T23:24:13.393058Z","shell.execute_reply":"2024-08-04T23:24:13.397482Z"},"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\n\n\nbase_model1.trainable = False\n\n\n\ninputs = tf.keras.Input(shape=(96,96,3))\n\nx = base_model1(inputs, training=False)\n  \nx = tf.keras.layers.Conv2D(filters=128, kernel_size=(3,3), activation = 'relu', padding = 'same')(x)\nx = tf.keras.layers.Conv2D(filters=128, kernel_size=(3,3), activation = 'relu', padding = 'same')(x)\nx = tf.keras.layers.MaxPooling2D(2,2, padding='same')(x)\nx = tf.keras.layers.Dropout(0.5)(x)\nx = tf.keras.layers.BatchNormalization()(x)\n\nx = tf.keras.layers.Flatten()(x)\n    \nx = tf.keras.layers.Dense(256, activation='relu')(x)\nx = tf.keras.layers.Dropout(0.5)(x)\nx = tf.keras.layers.Dense(128, activation='relu')(x)\nx = tf.keras.layers.Dropout(0.5)(x)\nx = tf.keras.layers.BatchNormalization()(x)\n\noutputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n\nmodel1 = tf.keras.Model(inputs, outputs)\n\n","metadata":{"execution":{"iopub.status.busy":"2024-08-04T23:24:13.399646Z","iopub.execute_input":"2024-08-04T23:24:13.399995Z","iopub.status.idle":"2024-08-04T23:24:15.502874Z","shell.execute_reply.started":"2024-08-04T23:24:13.399963Z","shell.execute_reply":"2024-08-04T23:24:15.502089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train Network","metadata":{}},{"cell_type":"code","source":"\nopt = tf.keras.optimizers.Adam(learning_rate=0.0001)\n\nmodel1.compile(optimizer=opt,\n              loss=tf.keras.losses.BinaryCrossentropy(),\n              metrics=[tf.keras.metrics.AUC()])","metadata":{"execution":{"iopub.status.busy":"2024-08-04T23:24:15.504192Z","iopub.execute_input":"2024-08-04T23:24:15.504560Z","iopub.status.idle":"2024-08-04T23:24:15.526198Z","shell.execute_reply.started":"2024-08-04T23:24:15.504523Z","shell.execute_reply":"2024-08-04T23:24:15.525457Z"},"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 = 20, \nvalidation_data = valid_loader, \nvalidation_steps = VA_STEPS, \nverbose = 1\n)","metadata":{"execution":{"iopub.status.busy":"2024-08-04T23:24:15.529546Z","iopub.execute_input":"2024-08-04T23:24:15.529841Z","iopub.status.idle":"2024-08-05T00:17:39.723947Z","shell.execute_reply.started":"2024-08-04T23:24:15.529817Z","shell.execute_reply":"2024-08-05T00:17:39.722956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = merge_history([h1])\nvis_training(history)","metadata":{"execution":{"iopub.status.busy":"2024-08-05T00:17:39.725758Z","iopub.execute_input":"2024-08-05T00:17:39.726430Z","iopub.status.idle":"2024-08-05T00:17:40.292501Z","shell.execute_reply.started":"2024-08-05T00:17:39.726390Z","shell.execute_reply":"2024-08-05T00:17:40.291559Z"},"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\n\n\nbase_model2.trainable = False\n\n\n\ninputs = tf.keras.Input(shape=(96,96,3))\n\nx = base_model2(inputs, training=False)\n  \nx = tf.keras.layers.Conv2D(filters=128, kernel_size=(3,3), activation = 'relu', padding = 'same')(x)\nx = tf.keras.layers.Conv2D(filters=128, kernel_size=(3,3), activation = 'relu', padding = 'same')(x)\nx = tf.keras.layers.MaxPooling2D(2,2, padding='same')(x)\nx = tf.keras.layers.Dropout(0.5)(x)\nx = tf.keras.layers.BatchNormalization()(x)\n\nx = tf.keras.layers.Flatten()(x)\n    \nx = tf.keras.layers.Dense(256, activation='relu')(x)\nx = tf.keras.layers.Dropout(0.5)(x)\nx = tf.keras.layers.Dense(128, activation='relu')(x)\nx = tf.keras.layers.Dropout(0.5)(x)\nx = tf.keras.layers.BatchNormalization()(x)\n\noutputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)\n\nmodel2 = tf.keras.Model(inputs, outputs)","metadata":{"execution":{"iopub.status.busy":"2024-08-05T00:19:41.587583Z","iopub.execute_input":"2024-08-05T00:19:41.588435Z","iopub.status.idle":"2024-08-05T00:19:43.148464Z","shell.execute_reply.started":"2024-08-05T00:19:41.588406Z","shell.execute_reply":"2024-08-05T00:19:43.147675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = tf.keras.optimizers.Adam(learning_rate=0.0001)\nmodel2.compile(optimizer=opt,\n              loss=tf.keras.losses.BinaryCrossentropy(),\n              metrics=[tf.keras.metrics.AUC()])","metadata":{"execution":{"iopub.status.busy":"2024-08-05T00:19:46.381718Z","iopub.execute_input":"2024-08-05T00:19:46.382471Z","iopub.status.idle":"2024-08-05T00:19:46.405313Z","shell.execute_reply.started":"2024-08-05T00:19:46.382441Z","shell.execute_reply":"2024-08-05T00:19:46.404493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.random.seed(1)\ntf.random.set_seed(1)\n\nh2 = model2.fit(\nx = train_loader, \nsteps_per_epoch = TR_STEPS, \nepochs = 20, \nvalidation_data = valid_loader, \nvalidation_steps = VA_STEPS, \nverbose = 1\n)","metadata":{"execution":{"iopub.status.busy":"2024-08-05T00:19:48.080549Z","iopub.execute_input":"2024-08-05T00:19:48.081385Z","iopub.status.idle":"2024-08-05T01:12:45.067829Z","shell.execute_reply.started":"2024-08-05T00:19:48.081350Z","shell.execute_reply":"2024-08-05T01:12:45.066641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = merge_history([h2])\nvis_training(history)","metadata":{"execution":{"iopub.status.busy":"2024-08-05T01:12:54.408164Z","iopub.execute_input":"2024-08-05T01:12:54.408892Z","iopub.status.idle":"2024-08-05T01:12:55.083618Z","shell.execute_reply.started":"2024-08-05T01:12:54.408863Z","shell.execute_reply":"2024-08-05T01:12:55.082745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1.save('Histopath_model_v12.1.h5')\npickle.dump(history, open(f'Histopath_history_v12.1.pk1', 'wb'))","metadata":{"execution":{"iopub.status.busy":"2024-08-05T01:13:03.643484Z","iopub.execute_input":"2024-08-05T01:13:03.644294Z","iopub.status.idle":"2024-08-05T01:13:04.010093Z","shell.execute_reply.started":"2024-08-05T01:13:03.644263Z","shell.execute_reply":"2024-08-05T01:13:04.009067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# End of code","metadata":{"execution":{"iopub.status.busy":"2024-08-05T00:17:46.772349Z","iopub.status.idle":"2024-08-05T00:17:46.772839Z","shell.execute_reply.started":"2024-08-05T00:17:46.772566Z","shell.execute_reply":"2024-08-05T00:17:46.772585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}