{"cells":[{"metadata":{},"cell_type":"markdown","source":"### Abstract\nWe consider a starter code for beginner of this dataset. There is a unbalanced distribution of the classes. To overcome this drawback we want to add images by modifying the given images. We use the following geometric transformations:\n* vertical flip,\n* rotation,\n* perspective transformation (zoom).\n\nAfter that we select randomly images by the same number of images of every class. \n\nIn consideration of the medical fact that there exists a course of disease we use multi-labels instead of single-labels. That means we set\n\n| diagnosis | single-label |multi-label |\n|---| ---| ---|\n| 0 | 0 | 0 |\n| 1 | 1 | 0, 1|\n| 2 | 2 | 0, 1, 2|\n| 3 | 3 | 0, 1, 2, 3|\n| 4 | 4 | 0, 1, 2, 3, 4|\n\nWe trained the model by using a pretrained model. "},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport random\n\nimport os\npath_in = \"../input/aptos2019-blindness-detection/\"\nprint(os.listdir(path_in))\nprint(os.listdir('../input/models'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import MultiLabelBinarizer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.utils import to_categorical\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D, Activation\nfrom keras.optimizers import RMSprop,Adam\nfrom keras.applications import VGG19","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Define some parameters"},{"metadata":{"trusted":true},"cell_type":"code","source":"q_size = 150\nimg_channel = 3\nnum_classes = 5","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Read the input csv files"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = pd.read_csv(path_in+'train.csv')\ntest_data = pd.read_csv(path_in+'test.csv')\nsub_org = pd.read_csv(path_in+'sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Define some functions"},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_bar(data):\n    \"\"\"Simple function to plot the distribution of the classes.\"\"\"\n    dict_data = dict(zip(range(0, num_classes), (((data.value_counts()).sort_index())).tolist()))\n    names = list(dict_data.keys())\n    values = list(dict_data.values())\n    plt.bar(names, values)\n    plt.grid()\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def read_images(filepath, data, file_list, size):\n    \"\"\"Read and edit the images of a given folder.\"\"\"\n    for file in file_list:\n        img = cv2.imread(filepath+file+'.png')\n        img = cv2.resize(img, (size, size))\n        img = cv2.addWeighted(img, 4, cv2.GaussianBlur(img, (0, 0), 10), -4, 128)\n        data[file_list.index(file), :, :, :] = img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def add_flip_image(data, file_list):\n    \"\"\"Simple function to flip images by a given list.\"\"\"\n    temp = np.empty((1, data.shape[1], data.shape[2], data.shape[3]), dtype=np.uint8)\n    for index in file_list.index:\n        img = data[index, :, :, :]\n        vertical_img = cv2.flip(img, 1)\n        temp[0, :, :, :] = vertical_img\n        data = np.concatenate((data, temp), axis=0)\n    return data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def add_rot_image(data, file_list):\n    \"\"\"Simple function to rotate images by a given list.\"\"\"\n    degrees = 15\n    temp = np.empty((1, data.shape[1], data.shape[2], data.shape[3]), dtype=np.uint8)\n    for index in file_list.index:\n        img = data[index, :, :, :]\n        rows,cols, channel = img.shape\n        Matrix = cv2.getRotationMatrix2D((cols/2,rows/2), degrees, 1)\n        rotate_img = cv2.warpAffine(img, Matrix, (cols, rows))\n        temp[0, :, :, :] = rotate_img\n        data = np.concatenate((data, temp), axis=0)\n    return data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def add_zoom_image(data, file_list):\n    \"\"\"Simple function to zoom in images by a given list.\"\"\"\n    temp = np.empty((1, data.shape[1], data.shape[2], data.shape[3]), dtype=np.uint8)\n    for index in file_list.index:\n        img = data[index, :, :, :]\n        size = img.shape[0]\n        pts1 = np.float32([[10,10],[size-10, 10],[10, size-10],[size-10, size-10]])\n        pts2 = np.float32([[0, 0],[size-20, 0],[0, size-20],[size-20, size-20]])\n        Matrix = cv2.getPerspectiveTransform(pts1, pts2)\n        # zoom image\n        img_zoom = cv2.warpPerspective(img, Matrix, (size-20, size-20))\n        dim = img.shape \n        # resize image\n        rows,cols, channel = img.shape\n        dim=(rows, cols)\n        img_scale = cv2.resize(img_zoom, dim, interpolation = cv2.INTER_AREA)\n        temp[0, :, :, :] = img_scale\n        data = np.concatenate((data, temp), axis=0)\n    return data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_multilabel(diagnosis):\n    \"\"\"A function to get multi-label from single-label.\"\"\"\n    return ','.join([str(i) for i in range(diagnosis + 1)])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Initialize the original train and test data"},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train_org = np.empty((len(train_data), q_size, q_size, img_channel), dtype=np.uint8)\nX_test = np.empty((len(test_data), q_size, q_size, img_channel), dtype=np.uint8)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Read the image data"},{"metadata":{"trusted":true},"cell_type":"code","source":"read_images(path_in+'train_images/', X_train_org, train_data['id_code'].tolist(), q_size)\nread_images(path_in+'test_images/', X_test, sub_org['id_code'].tolist(), q_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_bar(train_data['diagnosis'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Add flipped images\nDublicate the images from class 1 to 4 by vertical flip every image."},{"metadata":{"trusted":true},"cell_type":"code","source":"list_flip = train_data[train_data['diagnosis'] != 0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train_org = add_flip_image(X_train_org, list_flip)\ntrain_data = train_data.append(list_flip, ignore_index=True, sort=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_bar(train_data['diagnosis'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Add rotated images\nDublicate the images from class 1, 3 and 4 by rotate every image."},{"metadata":{"trusted":true},"cell_type":"code","source":"list_rot = train_data[(train_data['diagnosis'] != 0)&\n                      (train_data['diagnosis'] != 2)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train_org = add_rot_image(X_train_org, list_rot)\ntrain_data = train_data.append(list_rot, ignore_index=True, sort=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_bar(train_data['diagnosis'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Add images by zooming\nDublicate the images from class 3 and 4 by zooming every image."},{"metadata":{"trusted":true},"cell_type":"code","source":"list_zoom = train_data[(train_data['diagnosis'] == 3)|\n                       (train_data['diagnosis'] == 4)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train_org = add_zoom_image(X_train_org, list_zoom)\ntrain_data = train_data.append(list_zoom, ignore_index=True, sort=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_bar(train_data['diagnosis'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Select random images for train\nThe aim is to get equally distributed images for every class."},{"metadata":{"trusted":true},"cell_type":"code","source":"num_val = (train_data['diagnosis'].value_counts()).min()\nlist_new = []\nfor i in range(num_classes):\n    temp = random.choices(train_data[train_data['diagnosis']==i].index, k=num_val)\n    list_new.extend(temp)\ntrain_data = train_data.loc[list_new]\nX_train_org = X_train_org[list_new]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_bar(train_data['diagnosis'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Plot an image"},{"metadata":{"trusted":true},"cell_type":"code","source":"image_number=4019\nprint(train_data.iloc[image_number])\nplt.imshow(X_train_org[image_number], cmap='gray')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Prepare the labels\nUsing multi-label instead of single-label."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data['multilabel'] = train_data['diagnosis'].apply(get_multilabel)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"category =['0','1','2','3','4']\nMLB = MultiLabelBinarizer(category)\ny_train_org_multi = MLB.fit_transform(train_data['multilabel']).astype('float32')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Define class weights"},{"metadata":{"trusted":true},"cell_type":"code","source":"class_weight = dict(zip(range(0, num_classes), (((train_data['diagnosis'].value_counts()).sort_index())/len(train_data)).tolist()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Convert and scale image data"},{"metadata":{"trusted":true},"cell_type":"code","source":"mean = X_train_org.mean(axis=0)\nX_train_org = X_train_org.astype('float32')\nX_train_org -= X_train_org.mean(axis=0)\nstd = X_train_org.std(axis=0)\nX_train_org /= X_train_org.std(axis=0)\nX_test = X_test.astype('float32')\nX_test -= mean\nX_test /= std","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Split train and validation data"},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train, X_val, y_train, y_val = train_test_split(X_train_org, y_train_org_multi,\n                                                  test_size=0.1, random_state=0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Create the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"conv_base = VGG19(weights='../input/models/model_weights_vgg19.h5',\n                  include_top=False,\n                  input_shape=(q_size, q_size, img_channel))\nconv_base.trainable = True","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(conv_base)\nmodel.add(Flatten())\nmodel.add(Dense(512, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(5, activation='sigmoid'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer = Adam(lr=5e-7),\n              loss='binary_crossentropy',\n              metrics=['binary_accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 100\nbatch_size = 32","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Train the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(X_train, y_train,\n                    batch_size=batch_size,\n                    epochs=epochs,\n                    validation_data=(X_val, y_val),\n                    class_weight=class_weight)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Predict on the test images"},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test = model.predict(X_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test_classes = np.where(y_test>0.5, 1, 0).sum(axis=1)-1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Write output for submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"output = pd.DataFrame({'id_code': sub_org['id_code'],\n                       'diagnosis': y_test_classes})\noutput.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_bar(output['diagnosis'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Visualize the results"},{"metadata":{"trusted":true},"cell_type":"code","source":"loss = history.history['loss']\nloss_val = history.history['val_loss']\nepochs = range(1, len(loss)+1)\nplt.plot(epochs, loss, 'bo', label='loss_train')\nplt.plot(epochs, loss_val, 'b', label='los_val')\nplt.title('Value of the loss-function')\nplt.xlabel('Epochs')\nplt.ylabel('Value of the loss-function')\nplt.legend()\nplt.grid()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['binary_accuracy']\nacc_val = history.history['val_binary_accuracy']\nepochs = range(1, len(loss)+1)\nplt.plot(epochs, acc, 'bo', label='Accuracy_Train')\nplt.plot(epochs, acc_val, 'b', label='Accuracy_Val')\nplt.title('Value of the accurarcy')\nplt.xlabel('Epochs')\nplt.ylabel('Value of the accuracy')\nplt.legend()\nplt.grid()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del model","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":1}