{"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\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":{"trusted":true},"cell_type":"code","source":"!cp -r ../input/cassava-leaf-disease-classification ./","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#label training data based on the .csv\nfrom collections import defaultdict\nimport os\nimport pandas as pd\n\nif __name__ == '__main__':\n    df = pd.read_csv(\"./cassava-leaf-disease-classification/train.csv\", skipinitialspace=True)\n    counts = defaultdict(lambda: 1)\n    base_path = \"./cassava-leaf-disease-classification/train_images\"\n    for _, row in df.iterrows():\n        old_name, label = row[\"image_id\"], row[\"label\"]\n        new_name = counts[label]\n        label_path = f\"{base_path}/{label}\"\n        if not os.path.exists(label_path):\n            os.makedirs(label_path)\n        os.replace(f\"{base_path}/{old_name}\", f\"{label_path}/{new_name}.jpg\")\n        counts[label] += 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#make folder in which all trining data will be included resized\nimport os\n\n# define the name of the directory to be created\npath = \"./cassava-leaf-disease-classification/resized_images\"\n\ntry:\n    os.mkdir(path)\nexcept OSError:\n    print (\"Creation of the directory %s failed\" % path)\nelse:\n    print (\"Successfully created the directory %s \" % path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#resizing\nimport os\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' \nimport PIL.Image, tensorflow as tf, tensorflow.python.ops.image_ops as iops, numpy as np\ninput_dir = './cassava-leaf-disease-classification/train_images'\noutput_dir = './cassava-leaf-disease-classification/resized_images'\n\niops.resize_images_v2_ = iops.resize_images_v2\niops.resize_images_v2 = lambda *pargs, **nargs: iops.resize_images_v2_(*pargs, antialias = True, **nargs)\n\nds = tf.keras.preprocessing.image_dataset_from_directory(input_dir, image_size = (150, 150), interpolation = 'bicubic', shuffle = False)\nfor i, (images, labels) in enumerate(ds.as_numpy_iterator()):\n    for j, (image, label) in enumerate(zip(images, labels)):\n        os.makedirs(f'{output_dir}/{label}/', exist_ok = True)\n        if len(image.shape) == 0:\n            continue\n        print(f'{output_dir}/{label}/{i}_{j}.png')\n        PIL.Image.fromarray(np.clip(image, 0, 255).astype(np.uint8)).save(f'{output_dir}/{label}/{i}_{j}.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ##image resize ANOTHER WAY\n# import os, PIL.Image\n# input_dir = './cassava-leaf-disease-classification/train_images'\n# output_dir = './cassava-leaf-disease-classification/resized_data'\n# for (root, dirs, files) in os.walk(input_dir):\n#     for fname in files:\n#         print(root + '/' + fname, flush = True)\n#         img = PIL.Image.open(root + '/' + fname)\n#         img = img.resize((150, 150), PIL.Image.BICUBIC)\n#         os.makedirs(output_dir + '/' + root, exist_ok = True)\n#         img.save(output_dir + '/' + fname + '.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#print how many files available in training data folders\nimport os\n\nlist = os.listdir('./cassava-leaf-disease-classification/resized_images') # dir is your directory path\n#print(list)\nnumber_files = len(list)\nprint (number_files)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#make folder in which all trining data will be included\nimport os\n\n# define the name of the directory to be created\npath = \"./cassava-leaf-disease-classification/train_images_splitted\"\n\ntry:\n    os.mkdir(path)\nexcept OSError:\n    print (\"Creation of the directory %s failed\" % path)\nelse:\n    print (\"Successfully created the directory %s \" % path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install split-folders","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#in the link:https://github.com/jfilter/split-folders/blob/master/splitfolders/split.py you can see how the data should be shaped into folders \nimport splitfolders  # or import split_folders\n\n# Split with a ratio.\n# To only split into training and validation set, set a tuple to `ratio`, i.e, `(.8, .2)`.\nsplitfolders.ratio('./cassava-leaf-disease-classification/resized_images/', output='./cassava-leaf-disease-classification/train_images_splitted', seed=1337, ratio=(.8, .1, .1), group_prefix=None) # default values\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#print how many files available in training data folders\nimport os\n\nlist = os.listdir('./cassava-leaf-disease-classification/train_images_splitted') # dir is your directory path\nprint(list)\nnumber_files = len(list)\nprint (number_files)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd\n\nimport random\n\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img\n\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base_dir = os.path.join(\"./cassava-leaf-disease-classification/train_images_splitted\")\nprint(\"Base directory --> \", os.listdir(base_dir))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train set\ntrain_dir = os.path.join(\"./cassava-leaf-disease-classification/train_images_splitted/train/\")\nprint(\"Train --> \", os.listdir(train_dir))\n\n# Test set\ntest_dir = os.path.join(\"./cassava-leaf-disease-classification/train_images_splitted/test/\")\nprint(\"Test --> \", os.listdir(test_dir))\n\n# Validation set\nvalidation_dir = os.path.join(\"./cassava-leaf-disease-classification/train_images_splitted/val/\")\nprint(\"Validation --> \", os.listdir(validation_dir)[:5])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Displaying random image from the dataset\n\nfig, ax = plt.subplots(1, 5, figsize=(15, 10))\n\nsample_zero = random.choice(os.listdir(train_dir + \"0\"))\nimage = load_img(train_dir + \"0/\" + sample_zero)\nax[0].imshow(image)\nax[0].set_title(\"0\")\nax[0].axis(\"Off\")\n\nsample_one = random.choice(os.listdir(train_dir + \"1\"))\nimage = load_img(train_dir + \"1/\" + sample_one)\nax[1].imshow(image)\nax[1].set_title(\"1\")\nax[1].axis(\"Off\")\n\nsample_two = random.choice(os.listdir(train_dir + \"2\"))\nimage = load_img(train_dir + \"2/\" + sample_two)\nax[2].imshow(image)\nax[2].set_title(\"2\")\nax[2].axis(\"Off\")\n\nsample_three = random.choice(os.listdir(train_dir + \"3\"))\nimage = load_img(train_dir + \"3/\" + sample_three)\nax[3].imshow(image)\nax[3].set_title(\"3\")\nax[3].axis(\"Off\")\n\nsample_four = random.choice(os.listdir(train_dir + \"4\"))\nimage = load_img(train_dir + \"4/\" + sample_four)\nax[4].imshow(image)\nax[4].set_title(\"4\")\nax[4].axis(\"Off\")\n\n\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = tf.keras.models.Sequential([\n    \n    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),\n    tf.keras.layers.MaxPooling2D(2, 2),\n    \n    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    \n    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    \n    tf.keras.layers.Conv2D(128, (3,3), activation='relu'),\n    tf.keras.layers.MaxPooling2D(2,2),\n    \n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(512, activation='relu'),\n    \n    tf.keras.layers.Dense(5, activation='softmax')\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss = 'categorical_crossentropy',\n              optimizer = 'adam',\n              metrics = ['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class myCallback(tf.keras.callbacks.Callback):\n    def on_epoch_end(self, epoch, logs={}):\n        if(logs.get('accuracy')>0.95):\n            print(\"\\nReached >95% accuracy so cancelling training!\")\n            self.model.stop_training = True\n        \ncallbacks = myCallback()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n      rescale=1./255,\n      rotation_range=40,\n      width_shift_range=0.2, # Shifting image width by 20%\n      height_shift_range=0.2,# Shifting image height by 20%\n      shear_range=0.2,       # Rotation across X-axis by 20%\n      zoom_range=0.2,        # Image zooming by 20%\n      horizontal_flip=True,\n      fill_mode='nearest')\n\ntrain_generator = train_datagen.flow_from_directory(\n    train_dir,\n    target_size = (150, 150),\n    class_mode = 'categorical',\n    batch_size = 20\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_datagen = ImageDataGenerator(rescale=1./255)\n\nvalidation_generator = validation_datagen.flow_from_directory(\n    validation_dir,\n    target_size = (150, 150),\n    class_mode = 'categorical',\n    batch_size = 20\n)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# print([(sX, sY) for i, (X, Y) in zip(range(3), train_generator) for sX, sY in zip(X, Y)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train_generator_factory = lambda: train_datagen.flow_from_directory(\n#     train_dir, target_size = (150, 150), class_mode = 'categorical', batch_size = 20\n# )\n# Xtrain = np.concatenate([X for i, (X, Y) in zip(range(3), train_generator_factory())])\n# Ytrain = np.concatenate([Y for i, (X, Y) in zip(range(3), train_generator_factory())])\n# print(Xtrain.shape, Ytrain.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(\n      train_generator,\n      steps_per_epoch = np.ceil(17115/20),  # 2520 images = batch_size * steps\n      epochs = 10,\n      validation_data=validation_generator,\n      validation_steps = np.ceil(2146/20),  # 372 images = batch_size * steps\n      callbacks=[callbacks],\n      verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(len(acc))\n\nplt.figure(figsize=(7,7))\n\nplt.plot(epochs, acc, 'r', label='Training accuracy')\nplt.plot(epochs, val_acc, 'b', label='Validation accuracy')\nplt.title('Training and validation accuracy')\nplt.legend()\n\nplt.figure(figsize=(7,7))\n\nplt.plot(epochs, loss, 'r', label='Training Loss')\nplt.plot(epochs, val_loss, 'b', label='Validation Loss')\nplt.title('Training and validation loss')\nplt.legend()\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import classification_report, confusion_matrix,roc_curve, auc\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_datagen.flow_from_directory(\n    test_dir,\n    target_size=(150, 150),\n    batch_size=64,\n    class_mode='categorical',\n    shuffle=False\n)\ny_pred = model.predict(test_generator)\ny_test = test_generator.classes\ny_test_one_hot = pd.get_dummies(pd.Series(y_test)).values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"temp = y_pred.argmax(axis=1)\ncm = confusion_matrix(y_test, temp)\nprint('Confusion matrix')\nprint(cm)\nprint('Classification report')\nclasses = [\"Cassava Bacterial Blight (CBB)\", \"Cassava Brown Streak Disease (CBSD)\", \"Cassava Green Mottle (CGM)\", \"Cassava Mosaic Disease (CMD)\", \"Healthy\"]\nprint(classification_report(y_test, temp, target_names=classes))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"n_classes = 5\n# Compute ROC curve and ROC area for each class\nfpr = dict()\ntpr = dict()\nroc_auc = dict()\nfor i in range(n_classes):\n    fpr[i], tpr[i], _ = roc_curve(y_test_one_hot[:, i], y_pred[:, i])\n    roc_auc[i] = auc(fpr[i], tpr[i])\n\n# Plot of a ROC curve for a specific class\nfor i in range(n_classes):\n    plt.figure()\n    plt.plot(fpr[i], tpr[i], label='ROC curve (area = %0.2f)' % roc_auc[i])\n    plt.plot([0, 1], [0, 1], 'k--')\n    plt.xlim([0.0, 1.0])\n    plt.ylim([0.0, 1.05])\n    plt.xlabel('False Positive Rate')\n    plt.ylabel('True Positive Rate')\n    plt.title('Receiver operating characteristic example')\n    plt.legend(loc=\"lower right\")\n    plt.show()","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}