{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Imports","metadata":{"execution":{"iopub.status.busy":"2022-08-26T12:27:11.586282Z","iopub.execute_input":"2022-08-26T12:27:11.588806Z","iopub.status.idle":"2022-08-26T12:27:11.595736Z","shell.execute_reply.started":"2022-08-26T12:27:11.58876Z","shell.execute_reply":"2022-08-26T12:27:11.593969Z"}}},{"cell_type":"code","source":"import os\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom tqdm import tqdm, trange\n\n\nfrom skimage import io\nfrom skimage.transform import rescale, resize, downscale_local_mean\n\n\nimport matplotlib.pyplot as plt\nfrom matplotlib.pyplot import figure","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-11-14T16:22:59.356472Z","iopub.execute_input":"2022-11-14T16:22:59.356901Z","iopub.status.idle":"2022-11-14T16:23:00.269499Z","shell.execute_reply.started":"2022-11-14T16:22:59.356818Z","shell.execute_reply":"2022-11-14T16:23:00.268510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Loading","metadata":{}},{"cell_type":"code","source":"train_image_dir = \"../input/datathonindoml-2022/train/train\"\nvalid_image_dir = \"../input/datathonindoml-2022/validation/validation\"","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:00.271616Z","iopub.execute_input":"2022-11-14T16:23:00.271991Z","iopub.status.idle":"2022-11-14T16:23:00.278155Z","shell.execute_reply.started":"2022-11-14T16:23:00.271955Z","shell.execute_reply":"2022-11-14T16:23:00.276155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image_file_paths = [ os.path.join(train_image_dir, x) for x in os.listdir(train_image_dir)]\nvalid_image_file_paths = [ os.path.join(valid_image_dir, x) for x in os.listdir(valid_image_dir)]","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:00.588828Z","iopub.execute_input":"2022-11-14T16:23:00.589105Z","iopub.status.idle":"2022-11-14T16:23:01.085090Z","shell.execute_reply.started":"2022-11-14T16:23:00.589079Z","shell.execute_reply":"2022-11-14T16:23:01.084083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xlabels = pd.read_csv('../input/datathonindoml-2022/train_labels.csv')\nxlabels.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:01.558197Z","iopub.execute_input":"2022-11-14T16:23:01.558843Z","iopub.status.idle":"2022-11-14T16:23:01.593658Z","shell.execute_reply.started":"2022-11-14T16:23:01.558812Z","shell.execute_reply":"2022-11-14T16:23:01.592669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def find_file_id(path):\n    file_id = int((path.split(\"/\")[-1]).split(\".\")[0])\n    return file_id\n\ndef find_image_label(path):\n    file_id = find_file_id(path)\n    return (xlabels[xlabels.id==file_id]).values[0][1]\n\n\nprint(\"Path:\", train_image_file_paths[0])\nprint(\"File ID:\", find_file_id(train_image_file_paths[0]))\nprint(\"Label:\", find_image_label(train_image_file_paths[0]))","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:01.812972Z","iopub.execute_input":"2022-11-14T16:23:01.813331Z","iopub.status.idle":"2022-11-14T16:23:01.827592Z","shell.execute_reply.started":"2022-11-14T16:23:01.813300Z","shell.execute_reply":"2022-11-14T16:23:01.826389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_labels = [find_image_label(x) for x in train_image_file_paths]\ny_labels[:10]","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:02.020040Z","iopub.execute_input":"2022-11-14T16:23:02.020532Z","iopub.status.idle":"2022-11-14T16:23:06.867193Z","shell.execute_reply.started":"2022-11-14T16:23:02.020497Z","shell.execute_reply":"2022-11-14T16:23:06.866128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"xlabels.label.hist(bins=100)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:06.869054Z","iopub.execute_input":"2022-11-14T16:23:06.869706Z","iopub.status.idle":"2022-11-14T16:23:07.291094Z","shell.execute_reply.started":"2022-11-14T16:23:06.869667Z","shell.execute_reply":"2022-11-14T16:23:07.290188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"figure(figsize=(5, 5), dpi=100)\nidx = 98\nsample = train_image_file_paths[idx]\nsample_img = io.imread(sample)\nprint(sample, sample_img.shape, y_labels[idx])\nplt.imshow(sample_img, cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:07.293212Z","iopub.execute_input":"2022-11-14T16:23:07.293918Z","iopub.status.idle":"2022-11-14T16:23:07.620463Z","shell.execute_reply.started":"2022-11-14T16:23:07.293876Z","shell.execute_reply":"2022-11-14T16:23:07.619494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a={}\nfor idx, label in enumerate(y_labels):\n    if label not in a:\n        a[label] = idx\nprint(a)\nprint(len(a))\n\nfig, axis = plt.subplots(4, 4)\nfig.set_figheight(30)\nfig.set_figwidth(30)\n\na = list(a.values())\n\ntest_set = []\ntest_set_pred = []\n\nfor i in range(4):\n    for j in range(4):\n        idx = a[i*4 + j]\n        lbl = y_labels[idx]\n        sample = train_image_file_paths[idx]\n        test_set.append(sample)\n        test_set_pred.append(lbl)\n        sample_img = io.imread(sample)/255.0\n        axis[i, j].imshow(sample_img, cmap='gray')\n        axis[i, j].set_title(lbl)\n        del train_image_file_paths[idx]\n        del y_labels[idx]","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:07.622582Z","iopub.execute_input":"2022-11-14T16:23:07.623849Z","iopub.status.idle":"2022-11-14T16:23:11.656676Z","shell.execute_reply.started":"2022-11-14T16:23:07.623811Z","shell.execute_reply":"2022-11-14T16:23:11.654602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_image_file_paths), xlabels.shape[0]","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:11.658027Z","iopub.execute_input":"2022-11-14T16:23:11.658596Z","iopub.status.idle":"2022-11-14T16:23:11.665115Z","shell.execute_reply.started":"2022-11-14T16:23:11.658562Z","shell.execute_reply":"2022-11-14T16:23:11.664308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Generator","metadata":{}},{"cell_type":"code","source":"def prep_train_feature_data(paths, dim=(100,100)):\n    total=len(paths)\n    x = np.zeros((total, dim[0], dim[1], 3), dtype='float')\n    for i,path in (enumerate((paths))):\n        img = io.imread(path)/255.0\n        img =  resize(img, (dim[0], dim[1]))\n        img = img.reshape((dim[0], dim[1]))\n        x[i,:,:,0] = img\n        x[i,:,:,1] = img\n        x[i,:,:,2] = img\n    return x","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:11.666380Z","iopub.execute_input":"2022-11-14T16:23:11.667066Z","iopub.status.idle":"2022-11-14T16:23:11.675763Z","shell.execute_reply.started":"2022-11-14T16:23:11.667030Z","shell.execute_reply":"2022-11-14T16:23:11.675021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow import keras\n\nclass DataGenerator(keras.utils.Sequence):\n    def __init__(self, paths, batch_size=32, dim=(300, 300)):\n        'Initialization'\n        self.dim = dim\n        self.batch_size = batch_size\n        self.paths = paths\n\n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        return len(self.paths)//self.batch_size\n\n    def __getitem__(self, idx):\n        'Generate one batch of data'\n        # Generate indexes of the batch\n        index_start = idx*self.batch_size\n        index_end = (idx+1)*self.batch_size\n\n        sub_paths = self.paths[index_start:index_end]\n        \n        X = prep_train_feature_data(sub_paths, self.dim)\n        y = [find_image_label(path) for path in sub_paths]\n\n        return X, np.array(y)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:11.677122Z","iopub.execute_input":"2022-11-14T16:23:11.678011Z","iopub.status.idle":"2022-11-14T16:23:17.858413Z","shell.execute_reply.started":"2022-11-14T16:23:11.677977Z","shell.execute_reply":"2022-11-14T16:23:17.857448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_classes=len(set(y_labels))\nimage_size = (229, 229)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:17.859895Z","iopub.execute_input":"2022-11-14T16:23:17.860893Z","iopub.status.idle":"2022-11-14T16:23:17.866225Z","shell.execute_reply.started":"2022-11-14T16:23:17.860855Z","shell.execute_reply":"2022-11-14T16:23:17.865245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validation_data = prep_train_feature_data(test_set, image_size)\nvalidation_preds = np.array(test_set_pred)\nvalidation = (validation_data, validation_preds)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:17.867850Z","iopub.execute_input":"2022-11-14T16:23:17.868511Z","iopub.status.idle":"2022-11-14T16:23:18.191718Z","shell.execute_reply.started":"2022-11-14T16:23:17.868460Z","shell.execute_reply":"2022-11-14T16:23:18.190667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model - Transfer Learning Neural Nets","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:18.195456Z","iopub.execute_input":"2022-11-14T16:23:18.195816Z","iopub.status.idle":"2022-11-14T16:23:18.200783Z","shell.execute_reply.started":"2022-11-14T16:23:18.195788Z","shell.execute_reply":"2022-11-14T16:23:18.199722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input as resnet_process\nfrom tensorflow.keras.applications.vgg19 import VGG19, preprocess_input as vgg_process\n\ninput_shape = image_size\ninput_shape = input_shape + (3,)\ninputs = keras.Input(input_shape)\n\nimage_augment_input = layers.RandomFlip()(inputs) \nimage_augment_input = layers.RandomRotation(factor=1.0)(image_augment_input)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:18.202479Z","iopub.execute_input":"2022-11-14T16:23:18.202853Z","iopub.status.idle":"2022-11-14T16:23:22.390551Z","shell.execute_reply.started":"2022-11-14T16:23:18.202818Z","shell.execute_reply":"2022-11-14T16:23:22.389526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create the first base pre-trained model\n# model 1 output -  (None, 16, 16, 1280)  \nbase_model1 = ResNet50(weights='imagenet', include_top=False, input_shape=input_shape)\nbase_model1.trainable = False\n\nx1 = base_model1(image_augment_input, training=False)\nx1 = layers.Conv2D(512, 2, activation='relu')(x1)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:22.391799Z","iopub.execute_input":"2022-11-14T16:23:22.393454Z","iopub.status.idle":"2022-11-14T16:23:25.169645Z","shell.execute_reply.started":"2022-11-14T16:23:22.393404Z","shell.execute_reply":"2022-11-14T16:23:25.168338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create the secpmd base pre-trained model\n# model 2 output - (None, 16, 16, 1280)  \nbase_model2 = VGG19(weights='imagenet', include_top=False, input_shape=input_shape)\nbase_model2.trainable = False\n\nx2 = base_model2(image_augment_input, training=False)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:25.171027Z","iopub.execute_input":"2022-11-14T16:23:25.171379Z","iopub.status.idle":"2022-11-14T16:23:25.970592Z","shell.execute_reply.started":"2022-11-14T16:23:25.171345Z","shell.execute_reply":"2022-11-14T16:23:25.969543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = layers.Average()([x1, x2])\n\nx = layers.Flatten()(x)\nx = layers.Dense(1024, activation='relu')(x)\nx = layers.Dropout(0.5)(x)  # Regularize with dropout\noutputs = keras.layers.Dense(n_classes, activation='softmax')(x)\n\nmodel = keras.Model(inputs, outputs)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:25.971907Z","iopub.execute_input":"2022-11-14T16:23:25.972276Z","iopub.status.idle":"2022-11-14T16:23:26.016541Z","shell.execute_reply.started":"2022-11-14T16:23:25.972241Z","shell.execute_reply":"2022-11-14T16:23:26.015130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n    optimizer=keras.optimizers.Adam(),\n    loss=\"sparse_categorical_crossentropy\",\n    metrics=[\"accuracy\"],\n)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:26.017885Z","iopub.execute_input":"2022-11-14T16:23:26.018250Z","iopub.status.idle":"2022-11-14T16:23:26.033755Z","shell.execute_reply.started":"2022-11-14T16:23:26.018215Z","shell.execute_reply":"2022-11-14T16:23:26.032689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator = DataGenerator(train_image_file_paths, batch_size=128, dim=image_size)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:23:26.035241Z","iopub.execute_input":"2022-11-14T16:23:26.035582Z","iopub.status.idle":"2022-11-14T16:23:26.041261Z","shell.execute_reply.started":"2022-11-14T16:23:26.035548Z","shell.execute_reply":"2022-11-14T16:23:26.039194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 1\nhistory = model.fit(\n    train_generator, epochs=epochs, validation_data = validation\n)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:29:43.086816Z","iopub.execute_input":"2022-11-14T16:29:43.087237Z","iopub.status.idle":"2022-11-14T16:36:42.608291Z","shell.execute_reply.started":"2022-11-14T16:29:43.087177Z","shell.execute_reply":"2022-11-14T16:36:42.607238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model1.trainable = True\nbase_model2.trainable = True\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:38:26.506964Z","iopub.execute_input":"2022-11-14T16:38:26.507515Z","iopub.status.idle":"2022-11-14T16:38:26.545231Z","shell.execute_reply.started":"2022-11-14T16:38:26.507483Z","shell.execute_reply":"2022-11-14T16:38:26.544144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n    optimizer=keras.optimizers.Adam(1e-4),  # Low learning rate\n    loss=\"sparse_categorical_crossentropy\",\n    metrics=[\"accuracy\"],\n)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:38:27.862758Z","iopub.execute_input":"2022-11-14T16:38:27.863121Z","iopub.status.idle":"2022-11-14T16:38:27.878777Z","shell.execute_reply.started":"2022-11-14T16:38:27.863089Z","shell.execute_reply":"2022-11-14T16:38:27.877420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 1\ntrain_generator = DataGenerator(train_image_file_paths, batch_size=64, dim=image_size)\nhistory = model.fit(\n    train_generator, epochs=epochs, validation_data = validation\n)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:38:29.620796Z","iopub.execute_input":"2022-11-14T16:38:29.621172Z","iopub.status.idle":"2022-11-14T16:48:58.441283Z","shell.execute_reply.started":"2022-11-14T16:38:29.621141Z","shell.execute_reply":"2022-11-14T16:48:58.440239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluation","metadata":{}},{"cell_type":"code","source":"y_test_res = model.predict(validation_data)\nfor i in range(validation_data.shape[0]):\n    idx = np.argmax(y_test_res[i])\n    print(f\"Actual: {validation_preds[i]} Predicted: {idx}\")","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:49:55.312891Z","iopub.execute_input":"2022-11-14T16:49:55.313288Z","iopub.status.idle":"2022-11-14T16:49:56.629274Z","shell.execute_reply.started":"2022-11-14T16:49:55.313257Z","shell.execute_reply":"2022-11-14T16:49:56.628306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def pred_results(model, paths, img_size):\n    y_pred = []\n    for path in tqdm(paths):\n        test_data = prep_train_feature_data([path], img_size)\n        res = model.predict(test_data)\n        idx = np.argmax(res[0])\n        y_pred.append(idx)\n    return y_pred","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:50:00.178818Z","iopub.execute_input":"2022-11-14T16:50:00.179203Z","iopub.status.idle":"2022-11-14T16:50:00.185117Z","shell.execute_reply.started":"2022-11-14T16:50:00.179155Z","shell.execute_reply":"2022-11-14T16:50:00.184058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred_formatted = pred_results(model, valid_image_file_paths, image_size)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:50:04.760558Z","iopub.execute_input":"2022-11-14T16:50:04.760918Z","iopub.status.idle":"2022-11-14T16:51:52.702710Z","shell.execute_reply.started":"2022-11-14T16:50:04.760891Z","shell.execute_reply":"2022-11-14T16:51:52.701666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred_formatted","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:52:01.807313Z","iopub.execute_input":"2022-11-14T16:52:01.807695Z","iopub.status.idle":"2022-11-14T16:52:01.833248Z","shell.execute_reply.started":"2022-11-14T16:52:01.807664Z","shell.execute_reply":"2022-11-14T16:52:01.832340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids = [find_file_id(path) for path in valid_image_file_paths]","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:52:03.672814Z","iopub.execute_input":"2022-11-14T16:52:03.673202Z","iopub.status.idle":"2022-11-14T16:52:03.679989Z","shell.execute_reply.started":"2022-11-14T16:52:03.673153Z","shell.execute_reply":"2022-11-14T16:52:03.678593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission File","metadata":{}},{"cell_type":"code","source":"eval_df = pd.DataFrame()\neval_df['id'] = ids\neval_df['label'] = y_pred_formatted","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:52:37.385814Z","iopub.execute_input":"2022-11-14T16:52:37.386253Z","iopub.status.idle":"2022-11-14T16:52:37.399940Z","shell.execute_reply.started":"2022-11-14T16:52:37.386200Z","shell.execute_reply":"2022-11-14T16:52:37.398738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eval_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:52:37.926589Z","iopub.execute_input":"2022-11-14T16:52:37.927613Z","iopub.status.idle":"2022-11-14T16:52:37.938150Z","shell.execute_reply.started":"2022-11-14T16:52:37.927568Z","shell.execute_reply":"2022-11-14T16:52:37.937023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eval_df.shape","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:52:38.665505Z","iopub.execute_input":"2022-11-14T16:52:38.666252Z","iopub.status.idle":"2022-11-14T16:52:38.672905Z","shell.execute_reply.started":"2022-11-14T16:52:38.666208Z","shell.execute_reply":"2022-11-14T16:52:38.671746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eval_df.to_csv('submission_2.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-11-14T16:52:42.261214Z","iopub.execute_input":"2022-11-14T16:52:42.263482Z","iopub.status.idle":"2022-11-14T16:52:42.275361Z","shell.execute_reply.started":"2022-11-14T16:52:42.263426Z","shell.execute_reply":"2022-11-14T16:52:42.273172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}