{"cells":[{"metadata":{},"cell_type":"markdown","source":"# IMPORTS"},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport pandas as pd\nimport os\n\n#import json\n#import math\nimport cv2\nimport PIL\nfrom PIL import Image\nimport numpy as np\n\nfrom keras import layers\nfrom keras.applications import DenseNet121\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.optimizers import Adam\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\nimport scipy\n\nimport tensorflow as tf\n\nfrom tqdm import tqdm\n\nimport gc\n\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# DATA VALUES"},{"metadata":{"trusted":true},"cell_type":"code","source":"TESTING_PHASE=False\n\nBATCH_SIZE = 15\nTRAIN_VAL_RATIO = 0.27\nEPOCHS = 11\nLR = 0.001\nIMG_SIZE=128\nSEED=2020\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# LOAD AND PREPROCESS DATA"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/cassava-leaf-disease-classification/train.csv')\ntest_df = pd.read_csv('../input/cassava-leaf-disease-classification/sample_submission.csv')\nprint('train_df shape: ',train_df.shape)\nprint('test_df shape: ',test_df.shape)\nprint(train_df.head())\nprint(test_df.head())\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_mask_for_plant(image):\n    image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)\n\n    sensitivity = 35\n    lower_hsv = np.array([60 - sensitivity, 100, 50])\n    upper_hsv = np.array([60 + sensitivity, 255, 255])\n\n    mask = cv2.inRange(image_hsv, lower_hsv, upper_hsv)\n    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))\n    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)\n    \n    return mask\n\ndef segment_plant(image):\n    mask = create_mask_for_plant(image)\n    output = cv2.bitwise_and(image, image, mask = mask)\n    return output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocess_image(image_path, desired_size=IMG_SIZE):\n    \n    casava = cv2.imread(image_path)\n    im = cv2.resize(casava, (desired_size,desired_size), interpolation = cv2.INTER_AREA)\n    im = segment_plant(im)\n    im = Image.fromarray(im)\n    im = im.resize((desired_size,desired_size)) \n    im = np.array(im)\n    return im\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if TESTING_PHASE==True:\n    train_df=train_df.head(100)\n\n\n# number of training images from train dataset\nN = train_df.shape[0]\n# create an empty array for storing the images\nx_train = np.empty((N, IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)\n\n# store images in array\n\nfor i, image_id in enumerate(tqdm(train_df['image_id'])):\n    x_train[i, :, :, :] = preprocess_image(f'../input/cassava-leaf-disease-classification/train_images/{image_id}')\n  ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if os.path.exists('../input/cassava-leaf-disease-classification/test_images'):\n    # do the same thing as the last cell but on the test\\holdout set\n    N = test_df.shape[0]\n    x_test = np.empty((N, IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)\n    for i, image_id in enumerate(tqdm(test_df['image_id'])):\n        x_test[i, :, :, :] = preprocess_image(\n            f'../input/cassava-leaf-disease-classification/test_images/{image_id}'\n        )\nelse:\n    print(\"error: no image directory/files\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# one-hot encoding\ny_train = pd.get_dummies(train_df['label']).values\n\nprint(x_train.shape)\nprint(y_train.shape)\n\nif os.path.exists('../input/cassava-leaf-disease-classification/test_images'):\n    print(x_test.shape)\nelse:\n    print(\"test images not found\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# SHOW ONE DATA IMAGE"},{"metadata":{"trusted":true},"cell_type":"code","source":"image = cv2.imread(\"../input/cassava-leaf-disease-classification/train_images/1001749118.jpg\")\nplt.figure(figsize=(16,10))\nplt.imshow(image)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TRAIN"},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train, x_val, y_train, y_val = train_test_split(\n    x_train, y_train, \n    test_size=TRAIN_VAL_RATIO, \n    random_state=2021\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_datagen():\n    return ImageDataGenerator(\n        zoom_range=0.15,  # set range for random zoom\n        fill_mode='constant',\n        cval=0.,  # value used for fill_mode = \"constant\"\n        horizontal_flip=True,  # randomly flip images\n        vertical_flip=True,  # randomly flip images\n    )\n\n# Using original generator\ndata_generator = create_datagen().flow(x_train, y_train, batch_size=BATCH_SIZE, seed=SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# densenet = DenseNet121(\n#     weights='../input/densenet-keras/DenseNet-BC-121-32-no-top.h5',\n#     include_top=False,\n#     input_shape=(IMG_SIZE,IMG_SIZE,3)\n# )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def build_model(LR=LR):\n#     model = Sequential()\n#     model.add(densenet)\n#     model.add(layers.GlobalAveragePooling2D())\n#     model.add(layers.Dropout(0.80))\n#     model.add(layers.Dense(5, activation='sigmoid'))\n    \n#     model.compile(\n#         loss='binary_crossentropy',\n#         optimizer=Adam(lr=LR),\n#         metrics=['accuracy']\n#     )\n    \n#     return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"initial_learning_rate = 0.001 #initial rate\n# Rate decay with exponential decay\n# new rate = initial_learning_rate * decay_rate ^ (step / decay_steps)\n\nlr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(\n    initial_learning_rate,\n    decay_steps=800,\n    decay_rate=0.5,\n    staircase=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model(LR=LR):\n    \n    model = tf.keras.Sequential([\n    tf.keras.layers.Conv2D(64, 1, activation=None,kernel_regularizer=tf.keras.regularizers.l2(0.1), input_shape=(IMG_SIZE,IMG_SIZE,3)),\n    tf.keras.layers.MaxPooling2D(),\n    tf.keras.layers.BatchNormalization(axis=3),\n    tf.keras.layers.LeakyReLU(0.1),\n    tf.keras.layers.MaxPool2D(strides=2),\n    \n    tf.keras.layers.Conv2D(128, 3, activation=None,padding=\"same\",kernel_regularizer=tf.keras.regularizers.l2(0.01)),\n    tf.keras.layers.MaxPooling2D(),\n    tf.keras.layers.BatchNormalization(axis=3),\n    tf.keras.layers.LeakyReLU(0.1),\n    tf.keras.layers.MaxPool2D(strides=2),\n    \n    tf.keras.layers.Dropout(0.4),\n    \n    tf.keras.layers.Conv2D(256, 5, activation=None,kernel_regularizer=tf.keras.regularizers.l2(0.01)),\n    tf.keras.layers.BatchNormalization(axis=3),\n    tf.keras.layers.LeakyReLU(0.1),\n    tf.keras.layers.MaxPool2D(strides=2),\n    \n    tf.keras.layers.Conv2D(64, 5, activation=None,padding=\"same\",kernel_regularizer=tf.keras.regularizers.l2(0.01)),\n    tf.keras.layers.BatchNormalization(axis=3),\n    tf.keras.layers.LeakyReLU(0.1),\n    tf.keras.layers.MaxPool2D(strides=2),\n    \n    tf.keras.layers.Dropout(0.4),\n    \n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(100,kernel_regularizer=tf.keras.regularizers.l2(0.01), activation=None),\n    tf.keras.layers.BatchNormalization(axis=1),\n    tf.keras.layers.ReLU(),\n    \n    tf.keras.layers.Dropout(0.4),\n    tf.keras.layers.Dense(50,kernel_regularizer=tf.keras.regularizers.l2(0.01), activation=None),\n    tf.keras.layers.Dense(25,kernel_regularizer=tf.keras.regularizers.l2(0.01), activation=\"relu\"),\n    tf.keras.layers.BatchNormalization(axis=1),\n    tf.keras.layers.ReLU()])\n    model.add(layers.Dense(5, activation='softmax'))\n    \n    model.compile(\n        loss='categorical_crossentropy',\n        optimizer=Adam(learning_rate=lr_schedule),\n        metrics=['accuracy']\n    )\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = build_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(\n    data_generator,\n    steps_per_epoch=x_train.shape[0] / BATCH_SIZE,\n    epochs=100,\n    validation_data=(x_val, y_val)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history_df = pd.DataFrame(model.history.history)\nhistory_df[['loss', 'val_loss']].plot()\nhistory_df[['accuracy', 'val_accuracy']].plot()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# PREDICT"},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test = model.predict(x_test)\ny_test = np.argmax(y_test, axis=1)\ntest_df['label'] = y_test\ntest_df = test_df[[\"image_id\",\"label\"]]\ntest_df.to_csv('submission.csv',index=False)","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}