Cainvas
Model Files
Cotton_Disease.h5
keras
Model
deepSea Compiled Models
Cotton_Disease.exe
deepSea
Ubuntu

Cotton Plant Disease Prediction

Credit: AITS Cainvas Community

Photo by Pest Control Room

Aggriculture is an important backbone of any country and it boosts various industries such as food industry and textile industry.And when it comes to textile industry cotton producing crops hold a special position amongst all.Though there are some challenges faced by the cotton farmers and it is hard to cultivate them.After so many hardships if their crops get exposed to diseases and are not treated timely then it affects the life of farmers greatly.So in this notebook we have tried to implement a deep learning model to detect diseased cotton plants.

Importing the Dataset

In [1]:
!wget -N "https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/Cotton_Disease.zip"
!unzip -qo Cotton_Disease.zip 
!rm Cotton_Disease.zip
--2020-11-14 05:03:01--  https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/Cotton_Disease.zip
Resolving cainvas-static.s3.amazonaws.com (cainvas-static.s3.amazonaws.com)... 52.219.62.120
Connecting to cainvas-static.s3.amazonaws.com (cainvas-static.s3.amazonaws.com)|52.219.62.120|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 99391772 (95M) [application/zip]
Saving to: ‘Cotton_Disease.zip’

Cotton_Disease.zip  100%[===================>]  94.79M  62.6MB/s    in 1.5s    

2020-11-14 05:03:03 (62.6 MB/s) - ‘Cotton_Disease.zip’ saved [99391772/99391772]

Importing Libraries

In [2]:
# import libraries

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
from keras.layers import Dense, Flatten, AveragePooling2D, Dropout
from keras.models import Model
from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import Adam

Data Visualization

In [3]:
# Check images
img = cv2.imread("Cotton Disease/test/diseased cotton leaf/dis_leaf (124).jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.title("Diseased Cotton Leaf")
Out[3]:
Text(0.5, 1.0, 'Diseased Cotton Leaf')
In [4]:
# Check images
img = cv2.imread("Cotton Disease/test/fresh cotton leaf/d (122)_iaip.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.title("Fresh Cotton Leaf")
Out[4]:
Text(0.5, 1.0, 'Fresh Cotton Leaf')
In [5]:
# Check images
img = cv2.imread("Cotton Disease/test/diseased cotton plant/dd (16)_iaip.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.title("Diseased Cotton Plant")
Out[5]:
Text(0.5, 1.0, 'Diseased Cotton Plant')
In [6]:
# Check images
img = cv2.imread("Cotton Disease/test/fresh cotton plant/dsd (140)_iaip.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.title("Fresh Cotton Plant")
Out[6]:
Text(0.5, 1.0, 'Fresh Cotton Plant')

Loading the Data

In [7]:
train_generator= ImageDataGenerator(rescale=1./255,  shear_range=0.2, zoom_range=0.2, horizontal_flip=True)
test_generator= ImageDataGenerator(rescale=1./255,  shear_range=0.2, zoom_range=0.2, horizontal_flip=True)
In [8]:
train_data = train_generator.flow_from_directory( 'Cotton Disease/train', target_size=(224, 224),
        batch_size=64)
test_data = test_generator.flow_from_directory( 'Cotton Disease/test', target_size=(224, 224),
        batch_size=64)
Found 1041 images belonging to 4 classes.
Found 106 images belonging to 4 classes.
In [9]:
train_data.class_indices
Out[9]:
{'diseased cotton leaf': 0,
 'diseased cotton plant': 1,
 'fresh cotton leaf': 2,
 'fresh cotton plant': 3}

Using VGG-16 for Detecting plant disease

In [10]:
# Model creation with changes

model = VGG16(input_shape=(224,224,3),include_top=False)

for layer in model.layers:
    layer.trainable = False

newModel = model.output
newModel = AveragePooling2D()(newModel)
newModel = Flatten()(newModel)
newModel = Dense(128, activation="relu")(newModel)
newModel = Dropout(0.5)(newModel)
newModel = Dense(4, activation='softmax')(newModel)

model = Model(inputs=model.input, outputs=newModel)
In [11]:
model.summary()
Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 224, 224, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 56, 56, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 56, 56, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 56, 56, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 56, 56, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 28, 28, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 28, 28, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 28, 28, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 28, 28, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 14, 14, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0         
_________________________________________________________________
average_pooling2d (AveragePo (None, 3, 3, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 4608)              0         
_________________________________________________________________
dense (Dense)                (None, 128)               589952    
_________________________________________________________________
dropout (Dropout)            (None, 128)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 4)                 516       
=================================================================
Total params: 15,305,156
Trainable params: 590,468
Non-trainable params: 14,714,688
_________________________________________________________________

Model Training

In [12]:
opt=Adam(learning_rate=0.001)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
In [13]:
history = model.fit(train_data,
                              validation_data=test_data,
                              epochs=10) 
Epoch 1/10
17/17 [==============================] - 266s 16s/step - loss: 1.1548 - accuracy: 0.5082 - val_loss: 0.7070 - val_accuracy: 0.6226
Epoch 2/10
17/17 [==============================] - 265s 16s/step - loss: 0.6293 - accuracy: 0.7464 - val_loss: 0.5049 - val_accuracy: 0.7925
Epoch 3/10
17/17 [==============================] - 261s 15s/step - loss: 0.5097 - accuracy: 0.8079 - val_loss: 0.4274 - val_accuracy: 0.8679
Epoch 4/10
17/17 [==============================] - 263s 15s/step - loss: 0.4182 - accuracy: 0.8530 - val_loss: 0.4116 - val_accuracy: 0.8302
Epoch 5/10
17/17 [==============================] - 263s 15s/step - loss: 0.3866 - accuracy: 0.8636 - val_loss: 0.3706 - val_accuracy: 0.8679
Epoch 6/10
17/17 [==============================] - 265s 16s/step - loss: 0.3447 - accuracy: 0.8770 - val_loss: 0.3032 - val_accuracy: 0.8868
Epoch 7/10
17/17 [==============================] - 264s 16s/step - loss: 0.3005 - accuracy: 0.8934 - val_loss: 0.2648 - val_accuracy: 0.8774
Epoch 8/10
17/17 [==============================] - 264s 16s/step - loss: 0.2832 - accuracy: 0.9020 - val_loss: 0.2530 - val_accuracy: 0.8868
Epoch 9/10
17/17 [==============================] - 264s 16s/step - loss: 0.2687 - accuracy: 0.8953 - val_loss: 0.2814 - val_accuracy: 0.9151
Epoch 10/10
17/17 [==============================] - 261s 15s/step - loss: 0.2475 - accuracy: 0.9078 - val_loss: 0.2535 - val_accuracy: 0.9245

Training Plots

In [14]:
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs=range(len(acc))
In [15]:
plt.plot(epochs,acc,label='Trainin_acc',color='blue')
plt.plot(epochs,val_acc,label='Validation_acc',color='red')
plt.legend()
plt.title("Training and Validation Accuracy")
Out[15]:
Text(0.5, 1.0, 'Training and Validation Accuracy')
In [16]:
plt.plot(epochs,loss,label='Training_loss',color='blue')
plt.plot(epochs,val_loss,label='Validation_loss',color='red')
plt.legend()
plt.title("Training and Validation loss")
Out[16]:
Text(0.5, 1.0, 'Training and Validation loss')

Accessing the Performance of Model

In [17]:
class_dict = {0:'diseased cotton leaf',
              1:'diseased cotton plant',
              2:'fresh cotton leaf',
              3:'fresh cotton plant' }
In [18]:
# New Data for testing 

file_path =  'Cotton Disease/test/diseased cotton leaf/dis_leaf (153)_iaip.jpg'
test_image = cv2.imread(file_path)
test_image = cv2.cvtColor(test_image, cv2.COLOR_BGR2RGB)
test_image = cv2.resize(test_image, (224,224),interpolation=cv2.INTER_CUBIC)
plt.imshow(test_image)
test_image = np.expand_dims(test_image,axis=0)
probs = model.predict(test_image)
pred_class = np.argmax(probs)

pred_class = class_dict[pred_class]

print(pred_class)
diseased cotton leaf
In [19]:
file_path =  'Cotton Disease/test/diseased cotton plant/dd (885)_iaip.jpg'
test_image = cv2.imread(file_path)
test_image = cv2.cvtColor(test_image, cv2.COLOR_BGR2RGB)
test_image = cv2.resize(test_image, (224,224),interpolation=cv2.INTER_CUBIC)
plt.imshow(test_image)
test_image = np.expand_dims(test_image,axis=0)
probs = model.predict(test_image)
pred_class = np.argmax(probs)

pred_class = class_dict[pred_class]

print(pred_class)
diseased cotton plant
In [20]:
file_path =  'Cotton Disease/test/fresh cotton leaf/d (133)_iaip.jpg'
test_image = cv2.imread(file_path)
test_image = cv2.cvtColor(test_image, cv2.COLOR_BGR2RGB)
test_image = cv2.resize(test_image, (224,224),interpolation=cv2.INTER_CUBIC)
plt.imshow(test_image)
test_image = np.expand_dims(test_image,axis=0)
probs = model.predict(test_image)
pred_class = np.argmax(probs)

pred_class = class_dict[pred_class]

print(pred_class)
fresh cotton leaf
In [21]:
file_path =  'Cotton Disease/test/fresh cotton plant/dsd (223).jpg'
test_image = cv2.imread(file_path)
test_image = cv2.cvtColor(test_image, cv2.COLOR_BGR2RGB)
test_image = cv2.resize(test_image, (224,224),interpolation=cv2.INTER_CUBIC)
plt.imshow(test_image)
test_image = np.expand_dims(test_image,axis=0)
probs = model.predict(test_image)
pred_class = np.argmax(probs)

pred_class = class_dict[pred_class]

print(pred_class)
fresh cotton plant

Saving the model and Compiling the Model with DeepC

In [22]:
model.save("Cotton_Disease.h5")
In [23]:
!deepCC Cotton_Disease.h5
reading [keras model] from 'Cotton_Disease.h5'
Saved 'Cotton_Disease.onnx'
reading onnx model from file  Cotton_Disease.onnx
Model info:
  ir_vesion :  5 
  doc       : 
WARN (ONNX): graph-node block1_conv1's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block1_conv2's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block2_conv1's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block2_conv2's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block3_conv1's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block3_conv2's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block3_conv3's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block4_conv1's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block4_conv2's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block4_conv3's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block5_conv1's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block5_conv2's attribute auto_pad has no meaningful data.
WARN (ONNX): graph-node block5_conv3's attribute auto_pad has no meaningful data.
WARN (ONNX): terminal (input/output) input_1's shape is less than 1.
             changing it to 1.
WARN (ONNX): terminal (input/output) dense_1's shape is less than 1.
             changing it to 1.
WARN (GRAPH): found operator node with the same name (dense_1) as io node.
running DNNC graph sanity check ... passed.
Writing C++ file  Cotton_Disease_deepC/Cotton_Disease.cpp
INFO (ONNX): model files are ready in dir Cotton_Disease_deepC
g++ -std=c++11 -O3 -I. -I/opt/tljh/user/lib/python3.7/site-packages/deepC-0.13-py3.7-linux-x86_64.egg/deepC/include -isystem /opt/tljh/user/lib/python3.7/site-packages/deepC-0.13-py3.7-linux-x86_64.egg/deepC/packages/eigen-eigen-323c052e1731 Cotton_Disease_deepC/Cotton_Disease.cpp -o Cotton_Disease_deepC/Cotton_Disease.exe
Model executable  Cotton_Disease_deepC/Cotton_Disease.exe