{"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":"## This Notebook Uses ReSNet50 (Transfer Learning with PreTrained Weights and Retraining) Model to generate Output Predictions","metadata":{}},{"cell_type":"markdown","source":"#  <font color='red'>Table of Contents</font>\n","metadata":{}},{"cell_type":"markdown","source":"[9. ResNet50 Models](#section9)<br>\n","metadata":{"id":"I3BHeMMtWiIE"}},{"cell_type":"code","source":"# Research Kernel Link - https://github.com/dimitreOliveira/APTOS2019BlindnessDetection/blob/master/Model%20backlog/ResNet50/4%20-%20ResNet50%20-%20Batch%20size%2022.ipynb\n\nimport pandas as pd\nimport numpy as np\nimport os\nfrom prettytable import PrettyTable\nimport pickle\nimport multiprocessing\nfrom multiprocessing.pool import ThreadPool \nprint(multiprocessing.cpu_count(),\" CPU cores\")\nimport os\nprint('CWD is ',os.getcwd())\n\nimport seaborn as sns\n%matplotlib inline\nimport matplotlib.pyplot as plt\nplt.rcParams[\"axes.grid\"] = False\n\nfrom sklearn.metrics import confusion_matrix, cohen_kappa_score,accuracy_score\n\nfrom PIL import Image\nimport cv2\n\nimport tensorflow as tf \nimport keras\nfrom keras import applications\nfrom keras.applications.resnet import ResNet50\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import optimizers,Model,Sequential\nfrom keras.layers import Input,GlobalAveragePooling2D,Dropout,Dense,Activation,BatchNormalization,GlobalMaxPooling2D,concatenate,Flatten\nfrom keras.callbacks import EarlyStopping,ReduceLROnPlateau\n\n# Colab Libs...\n#from pydrive.auth import GoogleAuth\n#from pydrive.drive import GoogleDrive\n#from google.colab import auth\n#from oauth2client.client import GoogleCredentials","metadata":{"id":"22ccXpX_WQ54","outputId":"223b61e2-9b29-4677-8683-c8ad021ba2f0","execution":{"iopub.status.busy":"2022-12-18T18:17:37.968552Z","iopub.execute_input":"2022-12-18T18:17:37.969326Z","iopub.status.idle":"2022-12-18T18:17:44.961321Z","shell.execute_reply.started":"2022-12-18T18:17:37.969214Z","shell.execute_reply":"2022-12-18T18:17:44.960348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#  <a id = 'section9'> <font color='red'>  9. ResNet50 Models  </font> </a>","metadata":{"id":"yRu-rH5tWQ58"}},{"cell_type":"markdown","source":"### <font color='red'> 9.1 Setup Colab Environment </font>","metadata":{"id":"Ej-CCMUPW__D"}},{"cell_type":"code","source":"# Importing Libraries\n#ref - https://buomsoo-kim.github.io/colab/2018/04/16/Importing-files-from-Google-Drive-in-Google-Colab.md/\n\n# auth.authenticate_user()\n# gauth = GoogleAuth()\n# gauth.credentials = GoogleCredentials.get_application_default()\n# drive = GoogleDrive(gauth)","metadata":{"id":"AOPuWlg2W43_"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from google.colab import drive\n# drive.mount('/content/gdrive')","metadata":{"id":"P5s9LrQAXEBl","outputId":"1512d185-9d51-4dea-f89b-fc9ced7ad2cb"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n# os.chdir('/content/gdrive/My Drive/aptos2019')\n# print(\"We are currently in the folder of \",os.getcwd())","metadata":{"id":"UnaOi7ApXEEn","outputId":"b3809493-3a98-42d8-d647-33745d9c181d"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def load_data():\n#     file = open('df_train_train', 'rb')\n#     df_train_train = pickle.load(file)\n#     file.close()\n\n#     file = open('df_train_test', 'rb')\n#     df_train_test = pickle.load(file)\n#     file.close()\n    \n#     return df_train_train,df_train_test","metadata":{"id":"0cybxJXNWQ5-"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nThis function reads data from the respective train and test directories\n'''\n\ndef load_data():\n    train = pd.read_csv('/kaggle/input/aptos2019-blindness-detection/train.csv')\n    test = pd.read_csv('/kaggle/input/aptos2019-blindness-detection/test.csv')\n    \n    train_dir = os.path.join('./','/kaggle/input/aptos2019-blindness-detection/train_images/')\n    test_dir = os.path.join('./','/kaggle/input/aptos2019-blindness-detection/test_images/')\n    \n    train['file_path'] = train['id_code'].map(lambda x: os.path.join(train_dir,'{}.jpg'.format(x)))\n    test['file_path'] = test['id_code'].map(lambda x: os.path.join(test_dir,'{}.jpg'.format(x)))\n    \n    train['file_name'] = train[\"id_code\"].apply(lambda x: x + \".jpg\")\n    test['file_name'] = test[\"id_code\"].apply(lambda x: x + \".jpg\")\n    \n    train['diagnosis'] = train['diagnosis'].astype(str)\n    \n    return train,test","metadata":{"execution":{"iopub.status.busy":"2022-12-18T18:17:51.162302Z","iopub.execute_input":"2022-12-18T18:17:51.16305Z","iopub.status.idle":"2022-12-18T18:17:51.173993Z","shell.execute_reply.started":"2022-12-18T18:17:51.163004Z","shell.execute_reply":"2022-12-18T18:17:51.172912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_train,df_train_test = load_data()\nprint(df_train_train.shape,df_train_test.shape,'\\n')\ndf_train_train.head(6)","metadata":{"id":"z1F6Uye-WQ6D","outputId":"ed9b014f-f77d-4ceb-a114-7f4e7b8e20f0","execution":{"iopub.status.busy":"2022-12-18T18:18:45.296015Z","iopub.execute_input":"2022-12-18T18:18:45.296473Z","iopub.status.idle":"2022-12-18T18:18:45.345042Z","shell.execute_reply.started":"2022-12-18T18:18:45.296438Z","shell.execute_reply":"2022-12-18T18:18:45.344174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <font color='red'> 9.2 Image Pre Processing </font>","metadata":{"id":"3H9xIXaaMmza"}},{"cell_type":"code","source":"IMG_SIZE = 512","metadata":{"id":"SAct4MuUNjH4","execution":{"iopub.status.busy":"2022-12-18T18:18:52.929623Z","iopub.execute_input":"2022-12-18T18:18:52.930632Z","iopub.status.idle":"2022-12-18T18:18:52.935896Z","shell.execute_reply.started":"2022-12-18T18:18:52.930584Z","shell.execute_reply":"2022-12-18T18:18:52.934779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def crop_image_from_gray(img,tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n    #         print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n    #         print(img.shape)\n        return img\n\ndef circle_crop(img, sigmaX = 30):   \n    \"\"\"\n    Create circular crop around image centre    \n    \"\"\"    \n    img = crop_image_from_gray(img)    \n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    height, width, depth = img.shape    \n    \n    x = int(width/2)\n    y = int(height/2)\n    r = np.amin((x,y))\n    \n    circle_img = np.zeros((height, width), np.uint8)\n    cv2.circle(circle_img, (x,y), int(r), 1, thickness=-1)\n    img = cv2.bitwise_and(img, img, mask=circle_img)\n    img = crop_image_from_gray(img)\n    img=cv2.addWeighted(img,4, cv2.GaussianBlur( img , (0,0) , sigmaX) ,-4 ,128)\n    return img \n\ndef preprocess_image(file):\n    input_filepath = os.path.join('./','/kaggle/input/aptos2019-blindness-detection/train_images','{}.png'.format(file))\n    output_filepath = os.path.join('./','/kaggle/working/train_images_resized_preprocessed','{}.png'.format(file))\n    \n    img = cv2.imread(input_filepath)\n    img = circle_crop(img) \n    cv2.imwrite(output_filepath, cv2.resize(img, (IMG_SIZE,IMG_SIZE)))","metadata":{"id":"L6lBJR9tMo68","execution":{"iopub.status.busy":"2022-12-18T19:11:59.286321Z","iopub.execute_input":"2022-12-18T19:11:59.286676Z","iopub.status.idle":"2022-12-18T19:11:59.299385Z","shell.execute_reply.started":"2022-12-18T19:11:59.286647Z","shell.execute_reply":"2022-12-18T19:11:59.298371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs('/kaggle/working/train_images_resized_preprocessed')","metadata":{"execution":{"iopub.status.busy":"2022-12-18T19:10:44.475922Z","iopub.execute_input":"2022-12-18T19:10:44.47629Z","iopub.status.idle":"2022-12-18T19:10:44.481636Z","shell.execute_reply.started":"2022-12-18T19:10:44.47626Z","shell.execute_reply":"2022-12-18T19:10:44.480551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for file in df_train.id_code.values:\n   \n    preprocess_image(file)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''This Function uses Multi processing for faster saving of images into folder'''\n\ndef multiprocess_image_processor(process:int, imgs:list):\n    \"\"\"\n    Inputs:\n        process: (int) number of process to run\n        imgs:(list) list of images\n    \"\"\"\n    print(f'MESSAGE: Running {process} process')\n    results = ThreadPool(process).map(preprocess_image, imgs)\n    return results","metadata":{"id":"-VIgIRbCNBix","execution":{"iopub.status.busy":"2022-12-18T19:12:07.092418Z","iopub.execute_input":"2022-12-18T19:12:07.092777Z","iopub.status.idle":"2022-12-18T19:12:07.098121Z","shell.execute_reply.started":"2022-12-18T19:12:07.092744Z","shell.execute_reply":"2022-12-18T19:12:07.097136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Use 2 cores (colab)\n# ref - https://stackoverflow.com/questions/1006289/how-to-find-out-the-number-of-cpus-using-python\n\nmultiprocess_image_processor(2, list(df_train_train.id_code.values))","metadata":{"id":"Cf_-VV_DNC0N","execution":{"iopub.status.busy":"2022-12-18T19:16:26.008945Z","iopub.execute_input":"2022-12-18T19:16:26.009508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(os.listdir(\"/kaggle/working/test_images_resized_preprocessed\")),len(os.listdir(\"/kaggle/input/aptos2019-blindness-detection/test_images\")))","metadata":{"execution":{"iopub.status.busy":"2022-12-18T19:10:17.476928Z","iopub.execute_input":"2022-12-18T19:10:17.477622Z","iopub.status.idle":"2022-12-18T19:10:17.550896Z","shell.execute_reply.started":"2022-12-18T19:10:17.477586Z","shell.execute_reply":"2022-12-18T19:10:17.5498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <font color='red'> 9.3 Train Model </font>","metadata":{"id":"Oq5liZxiWQ6H"}},{"cell_type":"code","source":"# Model parameters\nBATCH_SIZE = 8\nEPOCHS = 40\nWARMUP_EPOCHS = 2\nLEARNING_RATE = 1e-4\nWARMUP_LEARNING_RATE = 1e-3\nHEIGHT = 320\nWIDTH = 320\nCANAL = 3\nN_CLASSES = df_train_train['diagnosis'].nunique()\nES_PATIENCE = 5\nRLROP_PATIENCE = 3\nDECAY_DROP = 0.5","metadata":{"id":"KBX1kOjkWQ6H"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def img_generator(train,test):\n    train_datagen=ImageDataGenerator(rescale=1./255, validation_split=0.2,horizontal_flip=True)\n    \n    train_generator=train_datagen.flow_from_dataframe(dataframe=df_train_train,\n                                                      directory=\"./train_images_resized_preprocessed/\",\n                                                      x_col=\"file_name\",\n                                                      y_col=\"diagnosis\",\n                                                      batch_size=BATCH_SIZE,\n                                                      class_mode=\"categorical\",\n                                                      target_size=(HEIGHT, WIDTH),\n                                                      subset='training')\n    \n    valid_generator=train_datagen.flow_from_dataframe(dataframe=df_train_train,\n                                                      directory=\"./train_images_resized_preprocessed/\",\n                                                      x_col=\"file_name\",\n                                                      y_col=\"diagnosis\",\n                                                      batch_size=BATCH_SIZE,\n                                                      class_mode=\"categorical\",    \n                                                      target_size=(HEIGHT, WIDTH),\n                                                      subset='validation')\n    \n    test_datagen = ImageDataGenerator(rescale=1./255)\n    test_generator = test_datagen.flow_from_dataframe(dataframe=df_train_test,\n                                                      directory = \"./test_images_resized_preprocessed/\",\n                                                      x_col=\"file_name\",\n                                                      target_size=(HEIGHT, WIDTH),\n                                                      batch_size=1,\n                                                      shuffle=False,\n                                                      class_mode=None)\n    \n    return train_generator,valid_generator,test_generator","metadata":{"id":"brHRA_U0WQ6K"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator,valid_generator,test_generator = img_generator(df_train_train,df_train_test)","metadata":{"id":"CQjnOOEhWQ6P","outputId":"703a18c6-c2d3-4d5a-c59e-26bc0d684180"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_model(input_shape, n_out):\n    input_tensor = Input(shape=input_shape)\n    base_model = applications.ResNet50(weights=None, include_top=False,input_tensor=input_tensor)\n    base_model.load_weights('resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')\n\n    x = GlobalAveragePooling2D()(base_model.output)\n    x = Dropout(0.5)(x)\n    x = Dense(2048, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    final_output = Dense(n_out, activation='softmax', name='final_output')(x)\n    model = Model(input_tensor, final_output)\n    return model","metadata":{"id":"p1ktmE4ZWQ6T"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model(input_shape=(HEIGHT, WIDTH, CANAL), n_out=N_CLASSES)\n\nfor layer in model.layers:\n    layer.trainable = False\n\nfor i in range(-5, 0):\n    model.layers[i].trainable = True\nmodel.summary()","metadata":{"id":"GIHj-I3LWQ6W","outputId":"438f8279-a839-406e-92a0-b28a6c13f7c6"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEP_SIZE_TRAIN = train_generator.n//train_generator.batch_size\nSTEP_SIZE_VALID = valid_generator.n//valid_generator.batch_size\nprint(STEP_SIZE_TRAIN,STEP_SIZE_VALID)","metadata":{"id":"FdOZMTWQWQ6Y","outputId":"669c9c51-fa6a-463b-d9e8-770aea573a0b"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer = optimizers.Adam(lr=WARMUP_LEARNING_RATE),loss = 'categorical_crossentropy',metrics = ['accuracy'])\n\nhistory_warmup = model.fit_generator(generator=train_generator,\n                                     steps_per_epoch=STEP_SIZE_TRAIN,\n                                     validation_data=valid_generator,validation_steps=STEP_SIZE_VALID,\n                                     epochs=WARMUP_EPOCHS,\n                                     verbose=1).history","metadata":{"id":"UR-WhqwSWQ6a","outputId":"3644a7a6-41c8-4449-9674-30613a0d9b1e"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers:\n    layer.trainable = True\n\nes = EarlyStopping(monitor='val_loss', mode='min', patience=ES_PATIENCE, restore_best_weights=True, verbose=1)\nrlrop = ReduceLROnPlateau(monitor='val_loss', mode='min', patience=RLROP_PATIENCE, factor=DECAY_DROP, min_lr=1e-6, verbose=1)\n\ncallback_list = [es, rlrop]\noptimizer = optimizers.Adam(lr=LEARNING_RATE)\nmodel.compile(optimizer=optimizer, loss=\"binary_crossentropy\",  metrics=['accuracy'])\nmodel.summary()","metadata":{"id":"I0EwusGsWQ6c","outputId":"265ae8eb-738f-48d1-93a8-9db67513a68d"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_finetunning = model.fit_generator(generator=train_generator,\n                                          steps_per_epoch=STEP_SIZE_TRAIN,\n                                          validation_data=valid_generator,\n                                          validation_steps=STEP_SIZE_VALID,\n                                          epochs=EPOCHS,\n                                          callbacks=callback_list,\n                                          verbose=1).history","metadata":{"id":"caeqUZYJWQ6k","outputId":"8c65ebfb-4637-4fed-d4dc-c76b495910d3"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ref - https://stackoverflow.com/questions/29188757/matplotlib-specify-format-of-floats-for-tick-lables\nplt.figure(figsize=(8,5))\n\nplt.plot(history_finetunning['accuracy'])\nplt.plot(history_finetunning['val_accuracy'])\nplt.title('Model Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left')\nplt.gca().ticklabel_format(axis='both', style='plain', useOffset=False)\nplt.show()","metadata":{"id":"UcLxU0ZhWQ6m","outputId":"3b67a6d9-2cc8-4753-8536-ef93939ed684"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <font color='red'> 9.4 Generate Train Predictions on complete Train Data </font>","metadata":{"id":"Cu1geHQHrINJ"}},{"cell_type":"code","source":"complete_datagen = ImageDataGenerator(rescale=1./255)\ncomplete_generator = complete_datagen.flow_from_dataframe(dataframe=df_train_train,\n                                                          directory = \"./train_images_resized_preprocessed/\",\n                                                          x_col=\"file_name\",\n                                                          target_size=(HEIGHT, WIDTH),\n                                                          batch_size=1,\n                                                          shuffle=False,\n                                                          class_mode=None)\n\nSTEP_SIZE_COMPLETE = complete_generator.n//complete_generator.batch_size\ntrain_preds = model.predict_generator(complete_generator, steps=STEP_SIZE_COMPLETE,verbose = 1)\ntrain_preds = [np.argmax(pred) for pred in train_preds]","metadata":{"id":"i4isFqHfrIcl","outputId":"d135af2f-266d-41b0-c438-c9e68290f02d"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Train Cohen Kappa score: %.3f\" % cohen_kappa_score(train_preds, df_train_train['diagnosis'].astype('int'), weights='quadratic'))\nprint(\"Train Accuracy score : %.3f\" % accuracy_score(df_train_train['diagnosis'].astype('int'),train_preds))","metadata":{"id":"y5coP6NwsHdS","outputId":"8d7348f1-698d-4352-ba68-bba45fca9663"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <font color='red'> 9.5 Evaluate Model on Test Data </font>","metadata":{"id":"ESdNiiRPWQ6o"}},{"cell_type":"code","source":"test_generator.reset()\nSTEP_SIZE_TEST = test_generator.n//test_generator.batch_size\ntest_preds = model.predict_generator(test_generator, steps=STEP_SIZE_TEST,verbose = 1)\ntest_labels = [np.argmax(pred) for pred in test_preds]","metadata":{"id":"vBjYmJDxnguQ","outputId":"534699c0-d5a3-40b6-8039-1b5d0ff81b66"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_conf_matrix(true,pred,classes):\n    cf = confusion_matrix(true, pred)\n    \n    df_cm = pd.DataFrame(cf, range(len(classes)), range(len(classes)))\n    plt.figure(figsize=(8,5.5))\n    sns.set(font_scale=1.4)\n    sns.heatmap(df_cm, annot=True, annot_kws={\"size\": 16},xticklabels = classes ,yticklabels = classes,fmt='g')\n    #sns.heatmap(df_cm, annot=True, annot_kws={\"size\": 16})\n    plt.show()","metadata":{"id":"qk-D7ZIvoEQ9"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = ['0 - No DR', '1 - Mild', '2 - Moderate', '3 - Severe', '4 - Proliferative DR']\nplot_conf_matrix(list(df_train_test['diagnosis'].astype(int)),test_labels,labels)","metadata":{"id":"8sxcjGJ1oR7f","outputId":"029b6c98-b913-4075-f4a1-13122acaf5ae"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cnf_matrix = confusion_matrix(df_train_test['diagnosis'].astype('int'), test_labels)\ncnf_matrix_norm = cnf_matrix.astype('float') / cnf_matrix.sum(axis=1)[:, np.newaxis]\ndf_cm = pd.DataFrame(cnf_matrix_norm, index=labels, columns=labels)\nplt.figure(figsize=(16, 7))\nsns.heatmap(df_cm, annot=True, fmt='.2f', cmap=\"Blues\")\nplt.show()","metadata":{"id":"23o5zz0XWQ6r","outputId":"37e5c873-fad8-4a5b-f272-1199944c9c7c"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Test Cohen Kappa score: %.3f\" % cohen_kappa_score(test_labels, df_train_test['diagnosis'].astype('int'), weights='quadratic'))\nprint(\"Test Accuracy score : %.3f\" % accuracy_score(df_train_test['diagnosis'].astype('int'),test_labels))","metadata":{"id":"ZViH2sI0WQ6v","outputId":"0204531e-ec13-4c63-c7eb-1e12d6391233"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <font color='red'> 9.6 ResNet50 Models Summary </font>","metadata":{"id":"wrNLulwLWQ62"}},{"cell_type":"code","source":"x = PrettyTable()\nx.field_names = [\"S.No.\",\"ResNet50 Model\",\"Image Processing\",\"Data Augmentation\",\"Hyperparameters(BS,Opt,lr,ep)\",\"Train QWK\",\"Test QWK\"]\n\nx.add_row([1,\"R-P-D-p(0.5)-D-p(0.5)-S(5)\",\"--\",\"Hor Flip,Scale 1/255\",\"(4,'Adam','1e-4',7)\",\"0.912\",\"0.905\"])\nx.add_row([2,\"R-P-D-p(0.5)-D-p(0.5)-S(5)\",\"Circle Crop, Gaussian Blur\",\"Hor Flip,Scale 1/255\",\"(4,'Adam','1e-4',7)\",\"0.98\",\"0.904\"])\n\nprint(x)","metadata":{"id":"ncmJ7qMzWQ62","outputId":"2f860351-5842-4a19-d260-d27da55b7954"},"execution_count":null,"outputs":[]}]}