{"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 in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"train=pd.read_csv(\"../input/aptos2019-blindness-detection/train.csv\")\ntest=pd.read_csv(\"../input/aptos2019-blindness-detection/test.csv\")\nsubmission_df=pd.read_csv(\"../input/aptos2019-blindness-detection/sample_submission.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\nsns.countplot(x='diagnosis',data=train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir ../data\n!mkdir ../data/train\n\n!mkdir ../data/train/0\n!mkdir ../data/train/1\n!mkdir ../data/train/2\n!mkdir ../data/train/3\n!mkdir ../data/train/4","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import subprocess\nfrom tqdm import tqdm\n\ndef move_img(df,kind):\n    for id_code ,diagnosis in tqdm(zip(df['id_code'],df['diagnosis'])):\n        if diagnosis == 0:\n            subprocess.call(['cp','../input/aptos2019-blindness-detection/{}_images/{}.png'.format(kind,id_code),'../data/{}/0/{}.png'.format(kind,id_code)])\n        if diagnosis == 1:\n            subprocess.call(['cp','../input/aptos2019-blindness-detection/{}_images/{}.png'.format(kind,id_code),'../data/{}/1/{}.png'.format(kind,id_code)])\n        if diagnosis == 2:\n            subprocess.call(['cp','../input/aptos2019-blindness-detection/{}_images/{}.png'.format(kind,id_code),'../data/{}/2/{}.png'.format(kind,id_code)])\n        if diagnosis == 3:\n            subprocess.call(['cp','../input/aptos2019-blindness-detection/{}_images/{}.png'.format(kind,id_code),'../data/{}/3/{}.png'.format(kind,id_code)])\n        if diagnosis == 4:\n            subprocess.call(['cp','../input/aptos2019-blindness-detection/{}_images/{}.png'.format(kind,id_code),'../data/{}/4/{}.png'.format(kind,id_code)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"move_img(train,'train')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\nprint(\"tensorflow version: {}\".format(tf.__version__))\n\nfrom tensorflow import keras\nprint(\"keras version: {}\".format(keras.__version__))\n\nimport numpy as np\nprint(\"numpy version: {}\".format(np.__version__))\n\nfrom keras import layers\nfrom keras import models\nfrom keras import optimizers\nfrom keras.preprocessing.image import ImageDataGenerator\n\nimport matplotlib.pyplot as plt\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\n\n\nclass MixupImageDataGenerator():\n    def __init__(self, generator, directory, batch_size, img_height, img_width, alpha=0.2, subset=None):\n        \"\"\"Constructor for mixup image data generator.\n\n        Arguments:\n            generator {object} -- An instance of Keras ImageDataGenerator.\n            directory {str} -- Image directory.\n            batch_size {int} -- Batch size.\n            img_height {int} -- Image height in pixels.\n            img_width {int} -- Image width in pixels.\n\n        Keyword Arguments:\n            alpha {float} -- Mixup beta distribution alpha parameter. (default: {0.2})\n            subset {str} -- 'training' or 'validation' if validation_split is specified in\n            `generator` (ImageDataGenerator).(default: {None})\n        \"\"\"\n\n        self.batch_index = 0\n        self.batch_size = batch_size\n        self.alpha = alpha\n\n        # First iterator yielding tuples of (x, y)\n        self.generator1 = generator.flow_from_directory(directory,\n                                                        target_size=(\n                                                            img_height, img_width),\n                                                        class_mode=\"categorical\",\n                                                        batch_size=batch_size,\n                                                        shuffle=True,\n                                                        subset=subset)\n\n        # Second iterator yielding tuples of (x, y)\n        self.generator2 = generator.flow_from_directory(directory,\n                                                        target_size=(\n                                                            img_height, img_width),\n                                                        class_mode=\"categorical\",\n                                                        batch_size=batch_size,\n                                                        shuffle=True,\n                                                        subset=subset)\n\n        # Number of images across all classes in image directory.\n        self.n = self.generator1.samples\n\n    def reset_index(self):\n        \"\"\"Reset the generator indexes array.\n        \"\"\"\n\n        self.generator1._set_index_array()\n        self.generator2._set_index_array()\n\n    def on_epoch_end(self):\n        self.reset_index()\n\n    def reset(self):\n        self.batch_index = 0\n\n    def __len__(self):\n        # round up\n        return (self.n + self.batch_size - 1) // self.batch_size\n\n    def get_steps_per_epoch(self):\n        \"\"\"Get number of steps per epoch based on batch size and\n        number of images.\n\n        Returns:\n            int -- steps per epoch.\n        \"\"\"\n\n        return self.n // self.batch_size\n\n    def __next__(self):\n        \"\"\"Get next batch input/output pair.\n\n        Returns:\n            tuple -- batch of input/output pair, (inputs, outputs).\n        \"\"\"\n\n        if self.batch_index == 0:\n            self.reset_index()\n\n        current_index = (self.batch_index * self.batch_size) % self.n\n        if self.n > current_index + self.batch_size:\n            self.batch_index += 1\n        else:\n            self.batch_index = 0\n\n        # random sample the lambda value from beta distribution.\n        l = np.random.beta(self.alpha, self.alpha, self.batch_size)\n\n        X_l = l.reshape(self.batch_size, 1, 1, 1)\n        y_l = l.reshape(self.batch_size, 1)\n\n        # Get a pair of inputs and outputs from two iterators.\n        X1, y1 = self.generator1.next()\n        X2, y2 = self.generator2.next()\n\n        # Perform the mixup.\n        X = X1 * X_l + X2 * (1 - X_l)\n        y = y1 * y_l + y2 * (1 - y_l)\n        return X, y\n\n    def __iter__(self):\n        while True:\n            yield next(self)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"input_generator = ImageDataGenerator(\n    preprocessing_function=keras.applications.mobilenet_v2.preprocess_input,\n    rotation_range=5,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.05,\n    zoom_range=0.2,\n    brightness_range=(1, 1.3),\n    horizontal_flip=True,\n    fill_mode='nearest',\n    validation_split=0.15\n)\n\n# Note that the validation data should not be augmented!\n#test_datagen = ImageDataGenerator(preprocessing_function=keras.applications.vgg16.preprocess_input)\n\nbatch_size = 32\nimg_height = 224\nimg_width = 224\ntrain_dir = '../data/train'\n\ntrain_generator = MixupImageDataGenerator(\n    generator=input_generator,                         \n    directory=train_dir,\n    batch_size=batch_size,\n    img_height=img_height,\n    img_width=img_width,\n    subset='training'\n)\n\nvalidation_generator = input_generator.flow_from_directory(\n    train_dir,\n    target_size=(img_height, img_width),\n    class_mode=\"categorical\",\n    batch_size=batch_size,\n    shuffle=True,    \n    subset='validation'\n)\n\nprint('training steps: ', train_generator.get_steps_per_epoch())\nprint('validation steps: ', validation_generator.samples // batch_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import DenseNet121\n\ndef get_pretrained_model():\n    conv_base = DenseNet121(\n        weights='../input/keras-applications-weights/densenet121_weights_tf_dim_ordering_tf_kernels_notop.h5',\n        include_top=False,\n        input_shape=(224, 224, 3)\n    )\n    conv_base.trainable = False\n    model = models.Sequential()\n    model.add(conv_base)\n    model.add(layers.GlobalAveragePooling2D())\n#     model.add(layers.Dropout(0.5))\n#     model.add(layers.Dense(2048, activation='relu'))\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(5, activation='softmax'))\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = get_pretrained_model()\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizers.RMSprop(lr=0.001),\n              metrics=['acc'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"early_stopping = keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    min_delta=0,\n    patience=10,\n    verbose=0,\n    mode='auto',\n    baseline=None,\n    restore_best_weights=False\n)\n\nmodel_checkpoint = keras.callbacks.ModelCheckpoint(\nfilepath='model.hdf5',\nmonitor='val_loss',\nverbose=1,\nsave_best_only=True,\nmode='min',\nperiod=1\n)\n\nreducelrtop = keras.callbacks.ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.1,\n    patience=10,\n    verbose=0,\n    mode='auto',\n    min_delta=0.0001,\n    cooldown=0,\n    min_lr=0\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":false,"_kg_hide-input":false},"cell_type":"code","source":"epochs = 2\n\nhistory = model.fit_generator(\n      train_generator,\n      steps_per_epoch=train_generator.get_steps_per_epoch(),\n      epochs=epochs,\n      max_queue_size=10,\n      workers=4,\n      validation_data=validation_generator,\n      validation_steps=validation_generator.samples // batch_size,\n      #callbacks=[model_checkpoint, early_stopping],\n      use_multiprocessing=True\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for layer in model.layers:\n    layer.trainable = True\n\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=optimizers.RMSprop(lr=0.0001),\n              metrics=['acc'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 30\n\nhistory = model.fit_generator(\n      train_generator,\n      steps_per_epoch=train_generator.get_steps_per_epoch(),\n      epochs=epochs,\n      max_queue_size=10,\n      workers=4,\n      validation_data=validation_generator,\n      validation_steps=validation_generator.samples // batch_size,\n      #callbacks=[model_checkpoint, early_stopping],\n      use_multiprocessing=True\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"hist = history\n\nfig, axes = plt.subplots(1, 2, figsize=(20, 5))\nax = axes[0]\nax.plot(hist.history['acc'], 'r', label='Training acc')\nax.plot(hist.history['val_acc'], 'g', label='Validation acc')\nax.set_title('Training and validation accuracy')\nax.legend()\n\nax = axes[1]\nax.plot(hist.history['loss'], 'r', label='Training loss')\nax.plot(hist.history['val_loss'], 'g', label='Validation loss')\nax.set_title('Training and validation loss')\nax.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_datagen = ImageDataGenerator(preprocessing_function=keras.applications.mobilenet_v2.preprocess_input)\n\ninput_dir = '../input/aptos2019-blindness-detection'\ntest_generator = test_datagen.flow_from_directory(\n    input_dir,\n    target_size=(224, 224),\n    color_mode=\"rgb\",\n    batch_size=1,\n    shuffle = False,\n    class_mode='categorical',\n    classes=['test_images']\n)\n\nfilenames = test_generator.filenames\nnb_samples = len(filenames)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predict = model.predict_generator(test_generator,steps = nb_samples)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.diagnosis = predict.argmax(1)\n\nsubmission_df.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}