{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-output":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\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 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\nimport os\nfor 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":{},"cell_type":"markdown","source":"## Import Libraries"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\n\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nfrom matplotlib.image import imread\n%matplotlib inline\n\n# tensorflow libraries\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, Model\nfrom keras.layers import Flatten, InputLayer, Dense, Conv2D, MaxPooling2D, Dropout\nfrom keras import optimizers\nfrom keras.applications.vgg16 import VGG16\nfrom keras.applications.inception_v3 import InceptionV3\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Reading Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission= pd.read_csv(\"/kaggle/input/cassava-leaf-disease-classification/sample_submission.csv\")\ntrain_df= pd.read_csv(\"/kaggle/input/cassava-leaf-disease-classification/train.csv\")\nclass_labels= pd.read_json(\"/kaggle/input/cassava-leaf-disease-classification/label_num_to_disease_map.json\", orient=\"index\")\n\n# class_labels = class_labels.values.flatten().tolist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### *Let's define image directories*"},{"metadata":{"trusted":true},"cell_type":"code","source":"base_dir= \"/kaggle/input/cassava-leaf-disease-classification\"\ntrain_img_dir=  \"/kaggle/input/cassava-leaf-disease-classification/train_images/\"\n\nprint(\"training images:\\n\", os.listdir(train_img_dir)[:5])\nprint(\"\\n Number of training images :\", len(os.listdir(train_img_dir)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### *Classes to which these training images belong to*"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(class_labels)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"\n#### *Let's find out the total number of Diseased and Healthy images*"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of healthy leaves images :\" , train_df[train_df[\"label\"] == 4].shape[0])\nprint(\"Number of diseased leaves images :\", train_df[train_df[\"label\"] != 4].shape[0])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### *Now let's take a look at a few pictures of what the diseased and healthy cells look like.*"},{"metadata":{"trusted":true},"cell_type":"code","source":"nrows = 4\nncols = 4\n\npic_index = 0 \n\nfig = plt.gcf()\nfig.set_size_inches(ncols*4, nrows*4)\n\npic_index+=8\n\nimages = [os.path.join(train_img_dir, image) \n                for image in os.listdir(train_img_dir)[ pic_index-8:pic_index] ]\n\n\nfor i, image_path in enumerate(images):\n  \n  sp = plt.subplot(nrows, ncols, i + 1)\n  sp.axis('Off')\n\n  img = mpimg.imread(image_path)\n  plt.imshow(img)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image= imread(\"/kaggle/input/cassava-leaf-disease-classification/train_images/1235188286.jpg\")\nimage.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Data Augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['label'] = train_df['label'].astype('string')\n\n# generating traning set\nprint(\"training set :\")\ntrain_datagen= ImageDataGenerator(rescale=1/255, zoom_range=0.3, rotation_range=50,\n                                   width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, \n                                   horizontal_flip=True, fill_mode='nearest', validation_split = 0.2)\n\ntrain_data= train_datagen.flow_from_dataframe(train_df,\n                                              train_img_dir,\n                                              target_size = (300, 300),\n                                              class_mode = \"categorical\",\n                                              batch_size = 20,\n                                              x_col = \"image_id\", y_col = \"label\",\n                                              shuffle = True, subset = \"training\")\n\n\n# generating validation set\nprint(\"\\nvalidation set :\")\nval_datagen= ImageDataGenerator(rescale=1/255, validation_split = 0.2)\n\nval_data= val_datagen.flow_from_dataframe(train_df,\n                                          train_img_dir,\n                                          target_size = (300, 300),\n                                          class_mode = \"categorical\",\n                                          batch_size = 20,\n                                          x_col = \"image_id\", y_col = \"label\",\n                                          shuffle = False, subset = \"validation\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inception ResnetV2 Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications import InceptionResNetV2\n\n# with include_top= False we are not using fully connected layer of the Inception_resnet model, instead we\n# will create our own Fully Connected and Output Layer according to our training data\ninception_resnet= InceptionResNetV2(input_shape= (300, 300,3), include_top= False, \n                       weights=\"../input/keras-pretrained-models/inception_resnet_v2_weights_tf_dim_ordering_tf_kernels_notop.h5\")\n\n\n# Since we are creating our own fully connected layer we need output of the last inception model layer and flatten them\nlast_output= inception_resnet.layers[-1].output\n\n# Flattening the last output\nlast_output= Flatten()(last_output)\n\n# pretrained model\ninception_model= Model(inception_resnet.input, last_output)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"inception_model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Creating Top Layers"},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"from keras import optimizers\n\nx= Dense(units= 512, activation= \"relu\")(last_output)\nx= Dropout(0.2)(x)\n\nx= Dense(units= 128, activation= \"relu\")(x)\nx= Dropout(0.2)(x)\n\nx= Dense(units= 5, activation= \"softmax\")(x)\n\n# final model\nmodel= Model(inception_model.input, x)\n\nmodel.compile(loss= \"categorical_crossentropy\", optimizer=optimizers.RMSprop(lr=1e-4), metrics=[\"accuracy\"])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Model Fitting"},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"# Since the layers of Inception_resnet model are already trained, we don't want them to be trained again. \n# So we will freeze them\nfor layer in inception_model.layers:\n    layer.trainable= False\n\n# fitting only Top layers     \nhistory= model.fit(train_data, epochs=20,\n                   steps_per_epoch= train_data.samples//train_data.batch_size,\n                   validation_data= val_data,\n                   validation_steps= val_data.samples//val_data.batch_size,\n                   batch_size= 20, verbose= 2)  ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Model Evaluation"},{"metadata":{"trusted":true},"cell_type":"code","source":"history.history.keys()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs= range(len(history.history[\"accuracy\"]))\n# accuracy plot\nplt.plot(epochs, history.history[\"accuracy\"])\nplt.plot(epochs, history.history[\"val_accuracy\"])\nplt.xlabel(\"epoch\")\nplt.ylabel(\"accuracy\")\nplt.title(\"Model Accuracy\")\nplt.legend([\"train\", \"validation\"])\nplt.show()\n\n# loss plot\nplt.plot(epochs, history.history[\"loss\"])\nplt.plot(epochs, history.history[\"val_loss\"])\nplt.xlabel(\"epoch\")\nplt.ylabel(\"loss\")\nplt.title(\"Model Loss\")\nplt.legend([\"train\", \"validation\"])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = []\nsample_submission = pd.read_csv('../input/cassava-leaf-disease-classification/sample_submission.csv')\n\nfor image in sample_submission.image_id:\n    img = tf.keras.preprocessing.image.load_img('../input/cassava-leaf-disease-classification/test_images/' + image)\n    img = tf.keras.preprocessing.image.img_to_array(img)\n    img = tf.keras.preprocessing.image.smart_resize(img, (300, 300))\n    img = tf.reshape(img, (-1, 300, 300, 3))\n    prediction = model.predict(img/255)\n    preds.append(np.argmax(prediction))\n\nsubmission = pd.DataFrame({'image_id': sample_submission.image_id, 'label': preds})\nsubmission.to_csv('submission.csv', index=False)        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}