{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport tensorflow as tf\nfrom sklearn.utils import class_weight\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\nsns.set()\nimport pandas as pd\nimport os\nimport json\n\nimport math\nfrom tensorflow import keras\nfrom sklearn.model_selection import train_test_split \nfrom sklearn.metrics import accuracy_score, confusion_matrix\n\nfrom tensorflow.keras.applications import EfficientNetB3, Xception, ResNet50V2\nfrom tensorflow.keras import layers\nfrom tensorflow.keras import models\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\nfrom tensorflow.keras.utils import plot_model\n\nfrom tensorflow.keras.preprocessing.image import load_img\nfrom tensorflow.keras.preprocessing.image import img_to_array","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image = tf.keras.preprocessing.image.load_img(r'../input/cassava-leaf-disease-classification/train_images/1000015157.jpg')\nimage","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Image Shape\nplt.imread('../input/cassava-leaf-disease-classification/train_images/1000015157.jpg').shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Path\npath = '../input/cassava-leaf-disease-classification'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Looking total fo images\ntrain_images = os.listdir(os.path.join(path, \"train_images\"))\nprint(\"Total images for Train: \", len(train_images))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Checking image's classes\nwith open ('../input/cassava-leaf-disease-classification/label_num_to_disease_map.json') as file:\n    classes = json.loads(file.read())\n    \nprint(json.dumps(classes,indent=4))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load the data\ndf_train = pd.read_csv(os.path.join(path, \"train.csv\"))\ndf_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Including the class names in the data\ndf_train['class'] = df_train['label'].map({int(i) : c for i, c in classes.items()}) \ndf_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plot of quantities by classes\nplt.subplots(figsize=(12,8))\nax  = sns.countplot(x='class', data=df_train)\n\nfor p in ax.patches:\n        ax.annotate('{:1}'.format(p.get_height()),\n                    (p.get_x()+0.3, p.get_height()))\nplt.xticks(rotation=90)\nax.set_title(\"quantities by classes\", fontdict={'fontsize':15})\nplt.show();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## We can see that there is an imbalance between classes. More than half of the data are from the Cassava Mosaic Disease Class (CMD)."},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:#4974a5; border:50; color:white'><center>Create Function for plot Images and Predictions<center><h2>\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot(images, labels, predictions = None):\n    n_cols = min(4, len(images))\n    n_rows = math.ceil(len(images) / n_cols)\n    fig, axes = plt.subplots(n_rows, n_cols, figsize = (21,16))\n\n    if predictions is None:\n              \n        predictions = [None] * len(labels)\n\n\n    for i, (x, y_true, y_pred) in enumerate(zip(images, labels, predictions)):\n        \n        ax = axes.flat[i]\n        a = plt.imread(os.path.join(path,\"train_images\", x ))\n        ax.imshow(a)\n\n        \n        ax.set_title(f\"Class: {y_true}\")\n             \n        if y_pred is not None:\n            ax.set_xlabel(f\"Pred: {y_pred}\", color='blue', fontweight='bold')\n\n        ax.set_xticks([])\n        ax.set_yticks([])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style='background:#4974a5; border:50; color:white'><center>Plotting samples of each class<center><h1>"},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:#4974a5; border:50; color:white'><center>Class 0 - Cassava Bacterial Blight (CBB) - Total: 1087<center><h2> "},{"metadata":{},"cell_type":"markdown","source":"Symptoms\nSmall, angular, brown, water-soaked lesions between leaf veins on lower surfaces of leaves; leaf blades turning brown as lesion expands; lesions may have a yello halo; lesions coalesce to form large necrotic patches; defoliation occurs with leaf petioles remaining in horizontal position as leaves drop; dieback of shoots; brown gum may be present on stems, leaves and petioles\n\nCause\nBacterium\n\nComments\nMost important bacterial disease of cassava; spread by water splash and infected tools; disease more severe in wet conditions; particularly destructive in South America and Africa; most important method of spread is probably through exchange of infected plant cuttings\n\nManagement\nRotate cassava crop with non-host; plow crop debris into soil after harvest or remove and burn it; prune infected parts from plant; propagate cuttings only from healthy plants; intercrop cassava with corn (maize) and melon"},{"metadata":{"trusted":true},"cell_type":"code","source":"# check the class\ndf_0 = df_train[df_train['label']==0]\ndf_0 = df_0.sample(12)\ndf_0_id = df_0['image_id'].values\ndf_0_class = df_0['class'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot(df_0_id, df_0_class)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:#4974a5; border:50; color:white'><center>Class 1 - Cassava Brown Streak Disease (CBSD) - Total: 2189 <center><h2>   \n"},{"metadata":{},"cell_type":"markdown","source":"Symptoms\nLeaves: \n\n- chlorotic or necrotic vein banding in mature leaves which may merge later to form large yellow patches\n\nStems:\n\n- Brown elongated necrotic lesions on young stems\n\nTubers:\n\n- necrosis of tubers\n\n- roots develop knots\n\n- internal tissues of roots and tubers stained brown and may rot due to secondary fungus infection\n\n1. yellowing along veins on lower/older leaves ~ 3 months after planting\n2. dark brown spots on upper green portion of stem ~ 6 months after planting\n3. Severe cases- leaf drying, shoot die-back\n4. In Tuber - Brown and hard rot when you cut into it. Causes malformation and root\nconstriction ~ 10 months after planting\n\nThe origin of CBSD is suspected to have arisen from the viruses that are already present on the indigenous African flora. Virus structure and properties: The microscopic studies revealed that the virus is 650 nm long and earlier it was believe to be carlavirus.\nDisease diagnosis: The first and foremost important aspect is to identify the disease correctly. Cassava brown streak disease varies in symptoms which made it difficult to identify in the field. It makes further complicated if both cassava brown streak and cassava mosaic diseases occur together. There are few techniques like serological and molecular methods are used to identify the virus in laboratory but have their limitations.\n\n<img src=\"https://s3.amazonaws.com/plantvillage-production-new/images/pics/000/001/095/original/Cassava_brown_streak_2.jpg?1375898926\" alt=\"Smiley face\" width=\"300\" height=\"300\" style=\"float:left\">"},{"metadata":{"trusted":true},"cell_type":"code","source":"# check the class\ndf_1 = df_train[df_train['label']==1]\ndf_1 = df_1.sample(12)\ndf_1_id = df_1['image_id'].values\ndf_1_class = df_1['class'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot(df_1_id, df_1_class)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:#4974a5; border:50; color:white'><center>Class 2 - Cassava Green Mottle (CGM) -  Total: 2386<center><h2> \n"},{"metadata":{},"cell_type":"markdown","source":"Scientific Name\nCassava green mottle nepovirus. It has not been confirmed to be a nepovirus; these are viruses that are transmitted by nematodes - hence the name.\n\nDistribution\nNarrow. Only known from Solomon Islands. It was first found on Choiseul in the 1970s; more recently (2010), similar symptoms were seen on Malaita.\n\nHosts\nIt is only known from cassava, and only from Choiseul (and possibly Malaita), nowhere else in the world. In the lab, several plant species have been infected with this virus; these species are known as \"indicator\" plants and are used to identify and characterise many kinds of viruses\n\nSymptoms & Life Cycle\nYoung leaves are puckered with faint to distinct yellow spots (Photo 1), green patterns (mosaics), and twisted margins (Photo 2). Usually, the shoots recover from symptoms and appear healthy. Occasionally, plants become severely stunted, edible roots are absent or, if present, they are small and woody when cooked.\n\nIn the lab, the virus can be passed between plants in sap, and also in seed. Thirty percent of the seed of infected tobacco plants was infected. Whether it also spreads in seed of cassava is unknown. Seed is not used for growing cassava, so spread on Choiseul is most likely in diseased cuttings. However, there are other possibilities.\n\nImpact\nSurveys on Chosieul showed that the disease is present in most plantings, but the number of infected plants is low. Cuttings taken from diseased plants are much slower to develop than those from plants without symptoms during the previous 9 months, and assumed to be healthy.\n\nDetection & Inspection\nLook for yellow patterns on the leaves, from small dots to irregular patches of yellow and green. Look for leaf margins that are distorted. The plants may be stunted."},{"metadata":{"trusted":true},"cell_type":"code","source":"# check the class\ndf_2 = df_train[df_train['label']==2]\ndf_2 = df_2.sample(12)\ndf_2_id = df_2['image_id'].values\ndf_2_class = df_2['class'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot(df_2_id, df_2_class)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:#4974a5; border:50; color:white'><center>Class 3 - Cassava Mosaic Disease (CMD) -  Total: 13158<center><h2> "},{"metadata":{},"cell_type":"markdown","source":"Symptoms\nDiscolored pale green, yellow or white mottled leaves which may be distorted with a reduced size; in highly susceptible cassava cultivars plant growth may be stunted, resulting in poor root yield and low quality stem cuttings.\n\n1. Patches of discolouration (chlorosis) in the leaves that vary from yellow to green.\n2. The leaves display size variation and are often severely distorted.\n3. Leaf blades sometimes fold depending on severity shrivel.\n\nCause\nVirus\nDisease is spread by infected cuttings and by whiteflies. The leaves are yellow, mottled and distorted. If leaves are yellow all over but are a normal size or there brown leaves that that does not indicate disease.\n\nVarieties of cassava resistant to the virus are available in many countries, most traditional varieties of cassava grown in Africa are susceptible to the virus, seek advice from an agricultural extension on suitable varieties for your region \n\n<img src=\"https://s3.amazonaws.com/plantvillage-production-new/images/pics/000/003/289/original/whiteflies2.jpg?1410805974\" alt=\"Smiley face\" width=\"250\" height=\"250\" style=\"float:left\">\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"# check the class\ndf_3 = df_train[df_train['label']==3]\ndf_3 = df_3.sample(12)\ndf_3_id = df_3['image_id'].values\ndf_3_class = df_3['class'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot(df_3_id, df_3_class)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h2 style='background:#4974a5; border:50; color:white'><center>Class 4 - Healthy - Total: 2577<center><h2>  "},{"metadata":{"trusted":true},"cell_type":"code","source":"# check the class\ndf_4 = df_train[df_train['label']==4]\ndf_4 = df_4.sample(12)\ndf_4_id = df_4['image_id'].values\ndf_4_class = df_4['class'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot(df_4_id, df_4_class)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style='background:#4974a5; border:50; color:white'><center>Augmentation techniques with Keras ImageDataGenerator<center><h1>  "},{"metadata":{},"cell_type":"markdown","source":"## Generate batches of tensor image data with real-time data augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Change Label from data to String\ntrain = df_train.astype({'label':str})\n# split data between training and test\n# we are using 20% for test\ntrain, test = train_test_split(train, test_size = .2, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style='background:#4974a5; border:50; color:white'><center>Model EfficientNetB3<center><h1> "},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating dataGernerator\ntrain_datagen = ImageDataGenerator(\n                    rotation_range = 45,\n                    width_shift_range = 0.2,\n                    height_shift_range = 0.2,\n                    shear_range = 0.2,\n                    zoom_range = 0.2,\n                    horizontal_flip = True,\n                    vertical_flip = True,\n                    fill_mode = 'nearest'\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Setting the image size for the model\nimg_size = 300\nsize = (img_size, img_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = train_datagen.flow_from_dataframe(\n                    train,\n                    directory = path+\"/train_images\",\n                    x_col = \"image_id\",\n                    y_col = \"class\",\n                    target_size = size,\n                    class_mode = \"categorical\",\n                    batch_size = 32,\n                    shuffle = True,\n                    seed = 42,\n                    interpolation = \"nearest\"\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_generator = train_datagen.flow_from_dataframe(\n                    test,\n                    directory = path+\"/train_images\",\n                    x_col = \"image_id\",\n                    y_col = \"class\",\n                    target_size = size,\n                    class_mode = \"categorical\",\n                    batch_size = 32,\n                    shuffle = False,\n                    seed = 42,\n                    interpolation = \"nearest\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating Model\ndef modelTransf():\n    \n    model = models.Sequential()\n    model.add(EfficientNetB3(input_shape = (img_size, img_size, 3), include_top = False, weights = 'imagenet'))\n    model.add(layers.GlobalAveragePooling2D())\n    model.add(layers.Dense(256, activation = 'relu'))\n    model.add(layers.Dense(256, activation = 'relu'))\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(5, activation = 'softmax'))\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = modelTransf()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Summary Model\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss = 'categorical_crossentropy',\n              optimizer = Adam(learning_rate = 0.001),\n              metrics = ['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"early_stopping = EarlyStopping(monitor = 'val_loss',\n                               patience = 10,\n                               mode = 'min', \n                               restore_best_weights = True)\n\ncheckpoint = ModelCheckpoint('modelB3.hdf5',\n                             monitor = 'val_loss',\n                             verbose = 1, mode = 'min',\n                             save_best_only = True)\n\nreduce_lr = ReduceLROnPlateau(monitor = 'val_loss',\n                              factor = 0.2,\n                              patience = 10,\n                              min_lr = 0.001,\n                              mode = 'min', \n                              verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"step_size_train = train_generator.n // train_generator.batch_size\nstep_size_test = test_generator.n // test_generator.batch_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"step_size_train, step_size_test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(train_generator,\n                    validation_data = test_generator,\n                    epochs = 30,\n                    steps_per_epoch = step_size_train,\n                    validation_steps = step_size_test,\n                    callbacks = [early_stopping, checkpoint, reduce_lr])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load Pre-trained model"},{"metadata":{"trusted":true},"cell_type":"code","source":"model_treined = keras.models.load_model('../input/model-trained/E_best_model.hdf5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filenames = test_generator.filenames\nlen(filenames)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions = model_treined.predict_generator(test_generator, steps = len(filenames))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions2 = []\nfor i in range(len(predictions)):\n    predictions2.append(np.argmax(predictions[i]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"accuracy_score(predictions2, test_generator.classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cfm = confusion_matrix(predictions2, test_generator.classes)\ncfm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.heatmap(cfm, annot=True, fmt=\"d\", cmap='viridis');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = pd.DataFrame(predictions2, columns=['class_pred'])\npred['pred'] = pred['class_pred'].map({int(i) : c for i, c in classes.items()})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_ids_test = test[\"image_id\"].values\nlabels_test = test[\"class\"].values\npred_result = pred['pred'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"rand_idxs = np.random.permutation(len(test))[:12]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot(image_ids_test[rand_idxs], labels_test[rand_idxs], pred_result[rand_idxs])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Make Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_file = pd.read_csv('../input/cassava-leaf-disease-classification/sample_submission.csv')\nsubmission_file","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path_test = '../input/cassava-leaf-disease-classification/test_images/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_img = os.listdir(path_test)\npredict = []\nfor image in test_img:\n    img = tf.keras.preprocessing.image.load_img(path_test + image)\n    img = img.resize((300, 300))\n    img = np.expand_dims(img, axis = 0)\n    predict.append(np.argmax(model_treined.predict(img)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predict","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.DataFrame({'image_id': test_img, 'label': predict})\nsubmission","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv', index = False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Thanks for reading, please give it an upvote. It is always greatly appreciated!"}],"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}