{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Introduction\n\nCreation of a base model (CNN) for Cassava Leaf Disease Classification competition.\n\n![](https://ak.picdn.net/shutterstock/videos/6440165/thumb/1.jpg)\n\n"},{"metadata":{},"cell_type":"markdown","source":"# Set up environment"},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Imports\nimport pandas as pd\nimport numpy as np\nimport tensorflow as tf\nimport tensorflow.keras as keras\nimport tensorflow.keras.layers as layers \nimport tensorflow.keras.layers.experimental.preprocessing as preprocessing\nimport seaborn as sns\nimport os, cv2, json, warnings\nwarnings.simplefilter(\"ignore\")\nimport matplotlib.pyplot as plt\nfrom matplotlib import gridspec\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.python.keras import optimizers\nfrom tensorflow.python.keras.models import Sequential\nfrom tensorflow.python.keras.layers import Dropout, Flatten, Dense, Activation\nfrom tensorflow.python.keras.layers import  Convolution2D, MaxPooling2D\nfrom tensorflow.python.keras import backend as K\ndef display_training_curves(training, validation, title, subplot):\n    if subplot%10==1: # set up the subplots on the first call\n        plt.subplots(figsize=(10,10), facecolor='#F0F0F0')\n        plt.tight_layout()\n    ax = plt.subplot(subplot)\n    ax.set_facecolor('#F8F8F8')\n    ax.plot(training)\n    ax.plot(validation)\n    ax.set_title('model '+ title)\n    ax.set_ylabel(title)\n    #ax.set_ylim(0.28,1.05)\n    ax.set_xlabel('epoch')\n    ax.legend(['train', 'valid.'])\nK.clear_session()\nWORK_DIR = '../input/cassava-leaf-disease-classification'\nos.listdir(WORK_DIR)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"print('Train images: %d' %len(os.listdir(\n    os.path.join(WORK_DIR, \"train_images\"))))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_labels = pd.read_csv(os.path.join(WORK_DIR, \"train.csv\"))\ntrain_labels","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"with open(os.path.join(WORK_DIR, \"label_num_to_disease_map.json\")) as file:\n    print(json.dumps(json.loads(file.read()), indent=4))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"![](https://neurohive.io/wp-content/uploads/2019/08/Screenshot-from-2019-08-26-23-19-25.png)"},{"metadata":{},"cell_type":"markdown","source":"# Set up variables"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"\"\"\"\nParameters\n\"\"\"\nBATCH_SIZE = 32\nEPOCHS = 100\nTARGET_SIZE = 512\nSTEPS = 133\nVALID_STEPS = 30\nLR = 0.0004\n\n# Reproducability\ndef set_seed(seed=27):\n    np.random.seed(seed)\n    tf.random.set_seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    os.environ['TF_DETERMINISTIC_OPS'] = '1'\nset_seed()\n\n# Set Matplotlib defaults\nplt.rc('figure', autolayout=True)\nplt.rc('axes', labelweight='bold', labelsize='large',\n       titleweight='bold', titlesize=18, titlepad=10)\nplt.rc('image', cmap='magma')\nwarnings.filterwarnings(\"ignore\") # to clean up output cells\n\n\ntrain_labels.label = train_labels.label.astype('str')\n\ntrain_datagen = ImageDataGenerator(validation_split = 0.2,\n                                   rescale=1. / 255,\n                                   rotation_range = 45,\n                                   zoom_range = 0.2,\n                                   horizontal_flip = True,\n                                   vertical_flip = True,\n                                   fill_mode = 'nearest',\n                                   shear_range = 0.2,\n                                   height_shift_range = 0.1,\n                                   width_shift_range = 0.1)\n\ntest_datagen = ImageDataGenerator(validation_split = 0.2,\n                                  rescale=1. / 255)\n\ntrain_generator = train_datagen.flow_from_dataframe(train_labels,\n                         directory = os.path.join(WORK_DIR, \"train_images\"),\n                         subset = \"training\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\")\n\ntest_generator = test_datagen.flow_from_dataframe(train_labels,\n                         directory = os.path.join(WORK_DIR, \"train_images\"),\n                         subset = \"validation\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"sns.set_style(\"whitegrid\")\nfig, ax = plt.subplots(figsize = (10, 4))\n\nfor i in ['top', 'right', 'left']:\n    ax.spines[i].set_visible(False)\nax.spines['bottom'].set_color('black')\n\nsns.countplot(train_labels.label, edgecolor = 'black',\n              palette = reversed(sns.color_palette(\"Spectral\", 5)))\nplt.xlabel('Classes', fontfamily = 'serif', size = 15)\nplt.ylabel('Count', fontfamily = 'serif', size = 15)\nplt.xticks(fontfamily = 'serif', size = 12)\nplt.yticks(fontfamily = 'serif', size = 12)\nax.grid(axis = 'y', linestyle = '--', alpha = 0.9)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Building the model"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"cnn = Sequential()\ncnn.add(Convolution2D(filters=32, kernel_size=5, padding =\"same\", input_shape=(TARGET_SIZE, TARGET_SIZE, 3), activation='relu'))\ncnn.add(MaxPooling2D(pool_size=(3,3)))\n\ncnn.add(Convolution2D(filters=64, kernel_size=3, padding =\"same\",activation='relu'))\ncnn.add(MaxPooling2D(pool_size=(3,3)))\n\ncnn.add(Convolution2D(filters=128, kernel_size=3, padding =\"same\",activation='relu'))\ncnn.add(MaxPooling2D(pool_size=(3,3)))\n\ncnn.add(Flatten())\ncnn.add(Dense(2048, activation='relu'))\ncnn.add(Dropout(0.5))\ncnn.add(Dense(5, activation='softmax'))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## summary\n\nThe 'sparse_categorical' versions of the loss and metrics are appropriate for a classification task with more than two labels."},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"cnn.compile(\n  optimizer=tf.keras.optimizers.Adam(learning_rate=LR),\n  loss='sparse_categorical_crossentropy',\n  metrics=['sparse_categorical_accuracy'])\n\ncnn.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Fit Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"history = cnn.fit_generator(\n    train_generator,\n    steps_per_epoch=STEPS,\n    epochs=EPOCHS,  \n    validation_data=test_generator,  \n    validation_steps=VALID_STEPS)\n    #callbacks = [early_stop])  ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Save Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"cnn.save('Model_3.h5')    \ncnn.save_weights('W_Model_3.h5')      ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display_training_curves( \n    history.history['loss'],\n    history.history['val_loss'], \n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history.history['sparse_categorical_accuracy'],\n    history.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212, \n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Work in progress ...**"}],"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}