{"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":"code","source":"import os\nimport shutil\nimport cv2\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow.keras.applications.vgg16 import preprocess_input, VGG16\nfrom sklearn.preprocessing import OneHotEncoder\nfrom sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\nfrom sklearn.model_selection import train_test_split\nimport yaml\n\nfrom kaggle_secrets import UserSecretsClient\nimport cv2\nimport pydicom\n\nfrom pathlib import Path\nfrom tqdm.auto import tqdm\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport skimage.io\nimport tqdm\nimport glob\nimport tensorflow\n\n# graphing\nimport matplotlib.image as mpimage\nimport matplotlib.pyplot as plt\n\n%matplotlib inline\n\nfrom PIL import Image\nimport random\nimport gc\nimport re\nimport cv2\nfrom tqdm import tqdm\nfrom sklearn.utils import shuffle\nfrom sklearn.model_selection import train_test_split\n\n# TF model stuff\nimport tensorflow as tf\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.models import Model,Sequential\nfrom tensorflow.keras.layers import Conv2D, Activation, MaxPooling2D, Dropout, GlobalAveragePooling1D, GlobalAveragePooling2D, Flatten, BatchNormalization, Dense\nfrom tensorflow.keras.optimizers import Adam, RMSprop, SGD\nfrom tensorflow.keras.applications.inception_v3 import InceptionV3, preprocess_input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nfrom sklearn.utils.class_weight import compute_class_weight\nfrom sklearn.metrics import accuracy_score, roc_auc_score, classification_report\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-24T03:16:30.155081Z","iopub.execute_input":"2021-06-24T03:16:30.155391Z","iopub.status.idle":"2021-06-24T03:16:36.372490Z","shell.execute_reply.started":"2021-06-24T03:16:30.155319Z","shell.execute_reply":"2021-06-24T03:16:36.371723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SIIM_COVID19_DETECTION_DIR = '../input/siim-covid19-detection/'\nPART0_RESIZED_DIR = '../input/siim-covid19-resized-to-512px-jpg/'\n\n\nTEMP_DIR = '/kaggle/temp/'\n\nINPUT_DIR = PART0_RESIZED_DIR+'/train/'\n\nOUTPUT_DIR = DATASET_DIR = TEMP_DIR+'/train/'\nTRAIN_DIR = DATASET_DIR + 'train/'\nTA_DIR = TRAIN_DIR+'ta/'\nIA_DIR = TRAIN_DIR+'ia/'\nAA_DIR = TRAIN_DIR+'aa/'\nNP_DIR = TRAIN_DIR+'np/'\n\nWORKING_DIR = '/kaggle/working/'\n\nWANDB_PROJECT_NAME = 'project8-kaggle-covid19'\nWANDB_ENTITY_NAME = ''\n\nTRAIN_IMAGE_LEVEL_PATH = SIIM_COVID19_DETECTION_DIR+'train_image_level.csv'\nTRAIN_STUDY_LEVEL_PATH = SIIM_COVID19_DETECTION_DIR+'train_study_level.csv'\nMETA_PATH = PART0_RESIZED_DIR+'meta.csv'\n\nBATCH_SIZE = 32\nEPOCHS = 25\nIMG_SIZE = WIDTH = HEIGHT = 224\nLEARNING_RATE = 0.00008\n\nINTERPOLATION = cv2.INTER_LANCZOS4","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:16:40.690960Z","iopub.execute_input":"2021-06-24T03:16:40.691326Z","iopub.status.idle":"2021-06-24T03:16:40.699301Z","shell.execute_reply.started":"2021-06-24T03:16:40.691280Z","shell.execute_reply":"2021-06-24T03:16:40.698163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_image_level = pd.read_csv(TRAIN_IMAGE_LEVEL_PATH)\ndf_train_study_level = pd.read_csv(TRAIN_STUDY_LEVEL_PATH)\n\ndf_train_image_level['id'] = df_train_image_level.apply(lambda row: row.id.split('_')[0], axis=1)\ndf_train_image_level['path'] = df_train_image_level.apply(lambda row: INPUT_DIR+row.id+'.jpg', axis=1)\ndf_train_image_level['image_level'] = df_train_image_level.apply(lambda row: row.label.split(' ')[0], axis=1)\n\ndf_train_study_level['id'] = df_train_study_level.apply(lambda row: row.id.split('_')[0], axis=1)\ndf_train_study_level.columns = ['StudyInstanceUID', 'Negative for Pneumonia', 'Typical Appearance', 'Indeterminate Appearance', 'Atypical Appearance']","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:16:44.021822Z","iopub.execute_input":"2021-06-24T03:16:44.022183Z","iopub.status.idle":"2021-06-24T03:16:44.562216Z","shell.execute_reply.started":"2021-06-24T03:16:44.022153Z","shell.execute_reply":"2021-06-24T03:16:44.561374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_image_level = df_train_image_level.merge(df_train_study_level, on='StudyInstanceUID',how=\"left\")\ndf_train_image_level = df_train_image_level[['id','StudyInstanceUID','path','Negative for Pneumonia','Typical Appearance','Indeterminate Appearance','Atypical Appearance']]\ndf_train_image_level = df_train_image_level.dropna()\ndf_train_image_level = df_train_image_level[~df_train_image_level.duplicated(subset=['StudyInstanceUID'], keep='first')]\ndf_train_image_level = df_train_image_level.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:16:46.300662Z","iopub.execute_input":"2021-06-24T03:16:46.301032Z","iopub.status.idle":"2021-06-24T03:16:46.336436Z","shell.execute_reply.started":"2021-06-24T03:16:46.300994Z","shell.execute_reply":"2021-06-24T03:16:46.335727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"[os.makedirs(dir, exist_ok=True) for dir in [TA_DIR,IA_DIR,AA_DIR,NP_DIR]]\nfor i in tqdm(range(len(df_train_image_level))):\n    row = df_train_image_level.loc[i]\n    if row['Typical Appearance']:\n        shutil.copy(row.path, f'{TA_DIR}{row.id}.jpg')\n    elif row['Indeterminate Appearance']:\n        shutil.copy(row.path, f'{IA_DIR}{row.id}.jpg')\n    elif row['Atypical Appearance']:\n        shutil.copy(row.path, f'{AA_DIR}{row.id}.jpg')\n    elif row['Negative for Pneumonia']:\n        shutil.copy(row.path, f'{NP_DIR}{row.id}.jpg')\n    else:\n        print('Error: check df_train_image_level')","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:16:48.620855Z","iopub.execute_input":"2021-06-24T03:16:48.621205Z","iopub.status.idle":"2021-06-24T03:17:39.929386Z","shell.execute_reply.started":"2021-06-24T03:16:48.621175Z","shell.execute_reply":"2021-06-24T03:17:39.928420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen_kwargs = dict(validation_split=.20,\n                      preprocessing_function=preprocess_input\n                     )\ndataflow_kwargs = dict(target_size=(IMG_SIZE, IMG_SIZE),\n                       batch_size=BATCH_SIZE,\n                       interpolation=\"lanczos\"\n                      )\n\nvalid_datagen = tf.keras.preprocessing.image.ImageDataGenerator(**datagen_kwargs)\nvalid_generator = valid_datagen.flow_from_directory(TRAIN_DIR,\n                                                    subset=\"validation\",\n                                                    shuffle=False,\n                                                    **dataflow_kwargs)\n\ntrain_datagen = tf.keras.preprocessing.image.ImageDataGenerator(\n    rotation_range=40,\n    horizontal_flip=True,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    **datagen_kwargs)\ntrain_generator = train_datagen.flow_from_directory(TRAIN_DIR,\n                                                    subset=\"training\",\n                                                    shuffle=True,\n                                                    **dataflow_kwargs)\n\nprint('classes :', train_generator.class_indices)","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:17:43.845297Z","iopub.execute_input":"2021-06-24T03:17:43.845705Z","iopub.status.idle":"2021-06-24T03:17:44.182577Z","shell.execute_reply.started":"2021-06-24T03:17:43.845670Z","shell.execute_reply":"2021-06-24T03:17:44.181808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model = VGG16(input_shape=(224,224,3), \n                         include_top=False,\n                         weights=\"imagenet\")","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:17:47.285327Z","iopub.execute_input":"2021-06-24T03:17:47.285651Z","iopub.status.idle":"2021-06-24T03:17:50.020345Z","shell.execute_reply.started":"2021-06-24T03:17:47.285619Z","shell.execute_reply":"2021-06-24T03:17:50.019443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in base_model.layers:\n    layer.trainable=False","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:17:51.571546Z","iopub.execute_input":"2021-06-24T03:17:51.571890Z","iopub.status.idle":"2021-06-24T03:17:51.578688Z","shell.execute_reply.started":"2021-06-24T03:17:51.571859Z","shell.execute_reply":"2021-06-24T03:17:51.577811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model=Sequential()\nmodel.add(base_model)\nmodel.add(Dropout(0.5))\nmodel.add(Flatten())\nmodel.add(BatchNormalization())\nmodel.add(Dense(2048,kernel_initializer='he_uniform'))\nmodel.add(BatchNormalization())\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1024,kernel_initializer='he_uniform'))\nmodel.add(BatchNormalization())\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(4,activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:17:53.427622Z","iopub.execute_input":"2021-06-24T03:17:53.427979Z","iopub.status.idle":"2021-06-24T03:17:53.562445Z","shell.execute_reply.started":"2021-06-24T03:17:53.427948Z","shell.execute_reply":"2021-06-24T03:17:53.561630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-23T18:54:52.010272Z","iopub.status.idle":"2021-06-23T18:54:52.010714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import plot_model\nfrom IPython.display import SVG, Image\nplot_model(model, to_file='model.png', show_shapes=True, show_layer_names=True)\nImage('model.png',width=400, height=200)","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:17:56.036587Z","iopub.execute_input":"2021-06-24T03:17:56.037023Z","iopub.status.idle":"2021-06-24T03:17:56.517043Z","shell.execute_reply.started":"2021-06-24T03:17:56.036980Z","shell.execute_reply":"2021-06-24T03:17:56.513224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"OPT    = tensorflow.keras.optimizers.Adam(lr=0.001)\n\nmodel.compile(loss='categorical_crossentropy',\n              metrics=[tensorflow.keras.metrics.AUC(name = 'auc')],\n              optimizer=OPT)","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:18:00.974178Z","iopub.execute_input":"2021-06-24T03:18:00.974526Z","iopub.status.idle":"2021-06-24T03:18:01.000643Z","shell.execute_reply.started":"2021-06-24T03:18:00.974490Z","shell.execute_reply":"2021-06-24T03:18:00.999867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filepath = './best_weights.hdf5'\n\nearlystopping = EarlyStopping(monitor = 'val_auc', \n                              mode = 'max' , \n                              patience = 15,\n                              verbose = 1)\n\ncheckpoint    = ModelCheckpoint(filepath, \n                                monitor = 'val_auc', \n                                mode='max', \n                                save_best_only=True, \n                                verbose = 1)\n\n\ncallback_list = [earlystopping, checkpoint]","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:18:03.600622Z","iopub.execute_input":"2021-06-24T03:18:03.601090Z","iopub.status.idle":"2021-06-24T03:18:03.608831Z","shell.execute_reply.started":"2021-06-24T03:18:03.601039Z","shell.execute_reply":"2021-06-24T03:18:03.607914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_history=model.fit(train_generator,\n                        validation_data=valid_generator,\n                        epochs = 30,\n                        callbacks = callback_list,\n                        verbose = 1)","metadata":{"execution":{"iopub.status.busy":"2021-06-24T03:18:06.477194Z","iopub.execute_input":"2021-06-24T03:18:06.477523Z","iopub.status.idle":"2021-06-24T08:45:34.024537Z","shell.execute_reply.started":"2021-06-24T03:18:06.477493Z","shell.execute_reply":"2021-06-24T08:45:34.023656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras\n#model.save('./best_weights.hdf5')\nmodel = keras.models.load_model('./best_weights.hdf5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Summarize history for loss\n\nplt.plot(model_history.history['accuracy'])\nplt.plot(model_history.history['val_accuracy'])\nplt.title('Model AUC')\nplt.ylabel('AUC')\nplt.xlabel('Epoch')\nplt.legend(['Train', 'Validation'], loc='upper left', bbox_to_anchor=(1,1))\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}