{"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":"# 1. Initialize","metadata":{}},{"cell_type":"code","source":"from numpy.random import seed\nseed(1)\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport os\nfrom glob import glob\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\n\nimport keras\nfrom keras.applications import Xception\nfrom keras.models import Sequential, Model\nfrom keras.layers import Activation,Dense, Dropout, Flatten, Conv2D, MaxPool2D,AveragePooling2D,GlobalMaxPooling2D\nfrom keras import backend as K\nfrom keras.wrappers.scikit_learn import KerasClassifier\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.utils.np_utils import to_categorical # convert to one-hot-encoding\nfrom keras import regularizers\nfrom keras.optimizers import Adam, SGD\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import ReduceLROnPlateau, EarlyStopping\n\nnp.random.seed(123)\n\nimport gc\nimport psutil\nfrom tqdm import tqdm\n\nprocess = psutil.Process(os.getpid())\ndef print_current_ram():\n    print(process.memory_info().rss / 1000000000, 'GB')","metadata":{"execution":{"iopub.status.busy":"2021-11-12T08:11:39.088722Z","iopub.execute_input":"2021-11-12T08:11:39.089198Z","iopub.status.idle":"2021-11-12T08:11:42.813010Z","shell.execute_reply.started":"2021-11-12T08:11:39.089091Z","shell.execute_reply":"2021-11-12T08:11:42.812151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Data\n\n## Ground Truth","metadata":{}},{"cell_type":"code","source":"df_gt = pd.read_csv('../input/isic-2019/ISIC_2019_Training_GroundTruth.csv', index_col='image')\ndf_gt","metadata":{"execution":{"iopub.status.busy":"2021-11-12T08:11:42.815187Z","iopub.execute_input":"2021-11-12T08:11:42.815561Z","iopub.status.idle":"2021-11-12T08:11:42.898245Z","shell.execute_reply.started":"2021-11-12T08:11:42.815524Z","shell.execute_reply":"2021-11-12T08:11:42.897551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## UQ Test Set","metadata":{}},{"cell_type":"code","source":"uq_test_set = {\n    'Melanocytic naevi': ['ISIC_0073202', 'ISIC_0073207', 'ISIC_0073208', 'ISIC_0073212', 'ISIC_0073219', 'ISIC_0073220', 'ISIC_0073222', 'ISIC_0073232', 'ISIC_0073240', 'ISIC_0073245'],\n    'Vascular skin lesions': ['ISIC_0071787', 'ISIC_0071912', 'ISIC_0072012', 'ISIC_0072430', 'ISIC_0072479', 'ISIC_0072651', 'ISIC_0072919', 'ISIC_0072964', 'ISIC_0073031', 'ISIC_0073110'],\n    'Dermatofibroma': ['ISIC_0071844', 'ISIC_0071858', 'ISIC_0071998', 'ISIC_0072033', 'ISIC_0072045', 'ISIC_0072137', 'ISIC_0072193', 'ISIC_0073112', 'ISIC_0073189', 'ISIC_0073193'],\n    'Benign keratosis': ['ISIC_1897507', 'ISIC_2140099', 'ISIC_2371734', 'ISIC_3409440', 'ISIC_4354896', 'ISIC_5215191', 'ISIC_5407240', 'ISIC_5958409', 'ISIC_6511141', 'ISIC_6594555'],\n    'Actinic keratosis': ['ISIC_0072940', 'ISIC_0072986', 'ISIC_0072992', 'ISIC_0073045', 'ISIC_0073068', 'ISIC_0073130', 'ISIC_0073153', 'ISIC_0073157', 'ISIC_0073214', 'ISIC_0073224'],\n    'Basal cell carcinoma': ['ISIC_0073155', 'ISIC_0073161', 'ISIC_0073170', 'ISIC_0073172', 'ISIC_0073196', 'ISIC_0073200', 'ISIC_0073221', 'ISIC_0073225', 'ISIC_0073229', 'ISIC_0073246'],\n    'Melanoma': ['ISIC_0073054', 'ISIC_0073065', 'ISIC_0073075', 'ISIC_0073097', 'ISIC_0073102', 'ISIC_0073115', 'ISIC_0073119', 'ISIC_0073127', 'ISIC_0073136', 'ISIC_0073143', 'ISIC_0073147', 'ISIC_0073156', 'ISIC_0073168', 'ISIC_0073173', 'ISIC_0073194', 'ISIC_0073203', 'ISIC_0073210', 'ISIC_0073218', 'ISIC_0073227', 'ISIC_0073231', 'ISIC_0073237', 'ISIC_0073238', 'ISIC_0073241', 'ISIC_0073249']\n}\nuq_test_ids = [y for x in uq_test_set.values() for y in x]","metadata":{"execution":{"iopub.status.busy":"2021-11-12T08:11:42.899494Z","iopub.execute_input":"2021-11-12T08:11:42.899838Z","iopub.status.idle":"2021-11-12T08:11:42.907443Z","shell.execute_reply.started":"2021-11-12T08:11:42.899811Z","shell.execute_reply":"2021-11-12T08:11:42.906444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Remove Test Set from Training Set","metadata":{}},{"cell_type":"code","source":"df_gt_remove_uq_test_set = df_gt.drop(uq_test_ids, errors='ignore')\ndisplay(df_gt_remove_uq_test_set)\nprint('Number of data removed:', len(df_gt) - len(df_gt_remove_uq_test_set))","metadata":{"execution":{"iopub.status.busy":"2021-11-12T08:11:42.909086Z","iopub.execute_input":"2021-11-12T08:11:42.909709Z","iopub.status.idle":"2021-11-12T08:11:42.943403Z","shell.execute_reply.started":"2021-11-12T08:11:42.909638Z","shell.execute_reply":"2021-11-12T08:11:42.942700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training Data","metadata":{}},{"cell_type":"code","source":"imx, imy = 128, 128","metadata":{"execution":{"iopub.status.busy":"2021-11-12T08:11:42.947189Z","iopub.execute_input":"2021-11-12T08:11:42.947460Z","iopub.status.idle":"2021-11-12T08:11:42.951258Z","shell.execute_reply.started":"2021-11-12T08:11:42.947430Z","shell.execute_reply":"2021-11-12T08:11:42.950320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_isic = []\nfor idx in tqdm(df_gt_remove_uq_test_set.index):\n    input_file_name = '../input/isic-2019/ISIC_2019_Training_Input/ISIC_2019_Training_Input/' + idx + '.jpg'\n    image_isic.append(np.asarray(Image.open(input_file_name).resize((imx,imy))))\n\nx_isic = np.asarray(image_isic)\n\ndel image_isic; gc.collect()","metadata":{"execution":{"iopub.status.busy":"2021-11-12T08:11:42.952869Z","iopub.execute_input":"2021-11-12T08:11:42.953562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_isic = np.asarray(df_gt_remove_uq_test_set)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train, x_validate, y_train, y_validate = train_test_split(x_isic, y_isic, test_size = 0.1, random_state=123)\ndel x_isic; del y_isic; gc.collect()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. Model","metadata":{}},{"cell_type":"code","source":"input_shape = (imy, imx, 3)\nnum_classes = 9\n\noptimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)\n\nepochs = 200\nbatch_size = 20\n\nlearning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', patience=5, verbose=1, factor=0.5, min_lr=0.00001)\nearly_stopping_monitor = EarlyStopping(patience=20, monitor='val_accuracy', restore_best_weights=True)\n\ndatagen = ImageDataGenerator(\n        featurewise_center=False,\n        samplewise_center=False,\n        featurewise_std_normalization=False,\n        samplewise_std_normalization=False,\n        zca_whitening=False,\n        rotation_range=90,\n        zoom_range = 0.1,\n        width_shift_range=0.1,\n        height_shift_range=0.1,\n        horizontal_flip=True,\n        vertical_flip=True,\n        shear_range = 10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_shape = (imy,imx,3)\nbase_model = Xception(include_top=False,weights='imagenet',input_shape = training_shape)\n\nXCeptionmodel = base_model.output\nXCeptionmodel = Flatten()(XCeptionmodel)\n\nXCeptionmodel = BatchNormalization()(XCeptionmodel)\nXCeptionmodel = Dense(128, activation='relu')(XCeptionmodel)\nXCeptionmodel = Dropout(0.2)(XCeptionmodel)\n\nXCeptionmodel = BatchNormalization()(XCeptionmodel)\nXCeptionoutput = Dense(num_classes, activation = 'softmax')(XCeptionmodel)\nXCeptionmodel = Model(inputs=base_model.input, outputs=XCeptionoutput)\n\nmodel = XCeptionmodel\n\nfor layer in base_model.layers:\n    layer.trainable = True","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer = optimizer , loss = \"categorical_crossentropy\", metrics=[\"accuracy\"])\nhistory = model.fit(datagen.flow(x_train,y_train, batch_size=batch_size),\n                    epochs = epochs, \n                    validation_data = (x_validate,y_validate),\n                    verbose = 1, steps_per_epoch=x_train.shape[0] // batch_size, \n                    callbacks=[learning_rate_reduction,early_stopping_monitor])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.evaluate(x_validate, y_validate, verbose=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4. Test","metadata":{}},{"cell_type":"code","source":"train_idx_to_legion = {\n    0: 'Melanoma',\n    1: 'Melanocytic naevi',\n    2: 'Basal cell carcinoma',\n    3: 'Actinic keratosis',\n    4: 'Benign keratosis',\n    5: 'Dermatofibroma',\n    6: 'Vascular skin lesions',\n    7: 'SCC',\n    8: 'UNK'\n}\n\nfor lesion in list(uq_test_set.keys())[:]:\n    print('===', lesion, '===')\n    \n    df = pd.DataFrame(columns=['[Result]'] + list(train_idx_to_legion.values()))    \n    success_num = 0\n    \n    for idx in uq_test_set[lesion]:\n        test_src_dir = '../input/siim-isic-melanoma-classification/jpeg/train/' if lesion == 'Benign keratosis' else '../input/isic-2019/ISIC_2019_Training_Input/ISIC_2019_Training_Input/'\n        test_image = np.asarray(Image.open(test_src_dir + idx + '.jpg').resize((imx, imy)))\n        test_x = np.expand_dims(test_image, axis=0)\n        test_y = model.predict(test_x)\n        \n        predict = train_idx_to_legion[test_y.argmax(axis=1)[0]]\n        df.loc[idx] = pd.Series([predict] + list(test_y[0]), index=df.columns)\n        if lesion == predict:\n            success_num += 1\n\n    display(df)\n    \n    total_num = len(uq_test_set[lesion])\n    print(f'-> {success_num} / {total_num} = {success_num / total_num * 100} %\\n')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5. References\n\nThis notebook is based on https://www.kaggle.com/jnegrini/ham10000-analysis-and-model-comparison","metadata":{}}]}