{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# # This Python 3 environment comes with many helpful analytics libraries installed\n# # It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# # For example, here's several helpful packages to load\n\n# import numpy as np # linear algebra\n# import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# # Input data files are available in the read-only \"../input/\" directory\n# # For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# # You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# # You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport sys\nimport random\nimport IPython\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\nfrom tensorflow import keras\n\nfrom sklearn.utils import shuffle\nfrom sklearn.datasets import make_classification\nfrom sklearn.metrics import confusion_matrix\n\nfrom matplotlib.pyplot import imread\nfrom cv2 import resize\nimport cv2\n\nfrom keras import layers\nfrom keras.layers import Input, Add, Dense,Dropout, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D\nfrom keras.models import Model, load_model\nfrom keras.preprocessing import image\nfrom keras.utils import layer_utils\nfrom keras.utils.data_utils import get_file\nfrom keras.applications.imagenet_utils import preprocess_input\nimport pydot\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.utils import plot_model\nfrom sklearn.preprocessing import OneHotEncoder\n\nfrom keras.initializers import glorot_uniform\nimport scipy.misc\nfrom matplotlib.pyplot import imshow\n\nrandom.seed = 2\nnp.random.seed = 2\ntf.seed = 2\ntf.random.set_seed(2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train Data Read"},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset_images_location = \"../input/aptos2019-blindness-detection/train_images\"\ndataset_groundtruth_location = \"../input/aptos2019-blindness-detection/train.csv\"\n\ndf = pd.read_csv(dataset_groundtruth_location)\ndf_ = pd.DataFrame();\ndf_['filename'] = df['id_code']+'.png'\ndf_['grade'] = df['diagnosis']\n\nlabels = np.array(df_['grade']).reshape(-1, 1)\nenc = OneHotEncoder(categories='auto', drop=None, sparse=False, dtype = np.int, handle_unknown='error')\nlabels = enc.fit_transform(labels)\n\na = []\nfor i in range(len(labels)):\n    a.append(str(labels[i]))\n    \ndf_['class'] = a\n\ndf = df_\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['grade'].hist(figsize = (10, 5))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def balance_data(class_size, df):\n    train_df = df.groupby(['grade']).apply(lambda x: x.sample(class_size, replace = True)).reset_index(drop = True)\n    train_df = train_df.sample(frac=1).reset_index(drop=True)\n    print('New Data Size:', train_df.shape[0], 'Old Size:', df.shape[0])\n    train_df['grade'].hist(figsize = (10, 5))\n    return train_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_df, val_df = train_test_split(df,test_size=0.1) # Here we will perform an 90%/10% split of the dataset, with stratification to keep similar distribution in validation set","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['grade'].hist(figsize = (10, 5))\nlen(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.pivot_table(index='grade', aggfunc=len)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = balance_data(train_df.pivot_table(index='grade', aggfunc=len).max().max(),train_df) # I will oversample such that all classes have the same number of images as the maximum\ntrain_df['grade'].hist(figsize = (10, 5))\nprint(len(train_df))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"bs = 16","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    vertical_flip=True,\n    rotation_range=5)\ntrain_generator = train_datagen.flow_from_dataframe(\n    train_df[['filename','class']],\n    \"../input/aptos2019-blindness-detection/train_images\",\n    target_size=(224,224),\n    batch_size=16,\n    class_mode='categorical')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model (ResNet50)"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.applications.resnet50 import ResNet50\nfrom keras.models import Model\nrestnet = ResNet50(include_top=False,weights=None,input_shape=(224,224,3))\noutput = restnet.layers[-1].output\noutput = keras.layers.Flatten()(output)\nrestnet = Model(restnet.input,output)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"restnet.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"restnet.trainable = True\nset_trainable = False\nfor layer in restnet.layers:\n    if layer.name in ['conv5_block3_2_conv','conv5_block3_3_conv' , 'conv5_block3_out']:\n        set_trainable = True\n    if set_trainable:\n        layer.trainable = True\n    else:\n        layer.trainable = False\nlayers = [(layer, layer.name, layer.trainable) for layer in restnet.layers]\npd.DataFrame(layers, columns=['Layer Type', 'Layer Name', 'Layer Trainable']).tail(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"input_shape=224,224,3\nmodel_finetuned = Sequential()#\nmodel_finetuned.add(restnet)\nmodel_finetuned.add(Dense(256, activation='relu'))\nmodel_finetuned.add(Dropout(0.3))\nmodel_finetuned.add(Dense(256, activation='relu'))\nmodel_finetuned.add(Dropout(0.3))\nmodel_finetuned.add(Dense(5, activation='softmax'))\n#model_finetuned.compile(loss='categorical_crossentropy',\n            #  optimizer=keras.optimizers.RMSprop(lr=1e-5),\n             # metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model Compile and Fit"},{"metadata":{"trusted":true},"cell_type":"code","source":"random.seed = 2\nnp.random.seed = 2\ntf.seed = 2\ntf.random.set_seed(2)\n\n#model = Resnet50(input_shape = (224, 224, 3), classes = 5)\nopt = keras.optimizers.Adam(learning_rate = 0.00008, beta_1 = 0.9)\nmodel_finetuned.compile(optimizer = opt, loss = 'categorical_crossentropy', metrics = ['accuracy'])\n\nearly_stopping= tf.keras.callbacks.EarlyStopping(monitor = 'accuracy', min_delta = 0.01, patience = 10)\n\n#train_generator = data_gen(train_df, enc)\n# val_generator = data_gen(val_df, enc)\n\nhist = model_finetuned.fit(train_generator,\n                 steps_per_epoch = int(len(train_df)/bs),\n                 epochs = 25, \n#                  validation_data = val_generator, \n#                  validation_steps = int(len(val_df) / bs),\n                 callbacks = [early_stopping], \n                 shuffle = True)\n\nprint('Done')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#serialize and save model \n# serialize model to JSON\nmodel_json = model.to_json()\nwith open(\"model_{}.json\".format('gradingNew11'), \"w\") as json_file:\n    json_file.write(model_json)\n# serialize weights to HDF5\nmodel.save_weights(\"model_{}.h5\".format('gradingNew11'))\nprint(\"Saved model to disk\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(hist.history['loss'])","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":4}