NOTE: This Use Case is not purposed for resource constrained devices.
In [1]:
# Import all the necessary libraries
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import Model
from tensorflow.keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import Sequential
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.models import load_model
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import os
import cv2
import pandas as pd
import random
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix
Unzip the Dataset¶
In [2]:
!wget 'https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/apple_leaf_2.zip'
!unzip -qo apple_leaf_2.zip
!rm apple_leaf_2.zip
In [3]:
train_path = os.path.join(os.getcwd(), 'apple_leaf')
os.listdir(train_path)
Out[3]:
Plotting Function to Visualize Images¶
In [4]:
# Get image as numpy array
def load_image(name, path):
img_path = os.path.join(path, name)
img = cv2.imread(img_path)
# img = load_img(img_path, target_size = (256, 256))
img = img[:,:, ::-1]
return img
# Plot numpy array
def plot_image(img, name, title):
plt.imshow(img)
plt.suptitle(title)
# Plot a grid of examples
def plot_grid(img_names, img_root, title ,rows=2, cols=3):
fig = plt.figure(figsize=(8,8))
for i,name in enumerate(img_names):
fig.add_subplot(rows,cols,i+1)
img = load_image(name, img_root)
plt.axis("off")
plot_image(img, name, title)
plt.show()
In [5]:
black_rot_path = os.path.join(train_path, "Apple Black Rot")
black_rot_images = os.listdir(black_rot_path)
plot_grid(black_rot_images[-6:], black_rot_path, title = "Apple Black Rot Images")
In [6]:
cedar_rust_path = os.path.join(train_path, "Apple Cedar Rust")
cedar_rust_images = os.listdir(cedar_rust_path)
plot_grid(cedar_rust_images[-6:], cedar_rust_path, title = "Apple Cedar Rust Images")
In [7]:
scab_path = os.path.join(train_path, "Apple Scab")
scab_images = os.listdir(scab_path)
plot_grid(scab_images[-6:], scab_path, title = "Apple Scab")
Define Image Data Generators¶
In [8]:
train_image_generator = ImageDataGenerator(
rescale = 1.0/255.0,
rotation_range = 40,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
validation_split = 0.2
)
valid_image_generator = ImageDataGenerator(
rescale = 1.0/2555.0,
rotation_range = 40,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
Defining the training and validation image data generator to expand our dataset of training and validation images. This is done by artificially generating new images by processing the exsisting images. By random flipping, rotating, scaling, and perfroming similar operations, we can create new images.
Loading Image Generators¶
In [9]:
batch_size = 20
training_images = train_image_generator.flow_from_directory(train_path,
target_size = (64,64),
class_mode = 'categorical',
batch_size = batch_size,
classes = os.listdir(train_path),
subset = 'training',
shuffle = True
#color_mode="grayscale"
)
validation_images = train_image_generator.flow_from_directory(train_path,
target_size = (64,64),
class_mode = 'categorical',
batch_size = batch_size,
classes = os.listdir(train_path),
subset = 'validation',
shuffle = True
#color_mode="grayscale"
)
Defining Model Architecture¶
In [10]:
# Defining the architecture for our neural network model
model=Sequential()
model.add(Conv2D(256,(2,2), activation='relu', input_shape=(64,64,3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128,(2,2), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64,(2,2), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32,(2,2), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(150,activation='relu'))
model.add(Dense(100,activation='relu'))
model.add(Dense(3, activation='sigmoid'))
model.summary()
In [11]:
model.compile(loss="categorical_crossentropy",
optimizer=Adam(learning_rate = 10 ** -3),
metrics=['accuracy'])
Train the Model¶
In [12]:
history = model.fit_generator(
training_images,
steps_per_epoch = training_images.samples // batch_size,
validation_data = validation_images,
validation_steps = validation_images.samples // batch_size,
epochs = 70,
#callbacks = [es]
)
In [13]:
model.save('best_model.h5')
In [14]:
# Function to plot "accuracy vs epoch" graphs and "loss vs epoch" graphs for training and validation data
def plot_metrics(model_name, metric = 'accuracy'):
if metric == 'loss':
plt.title("Loss Values")
plt.plot(model_name.history['loss'], label = 'train')
plt.plot(model_name.history['val_loss'], label = 'test')
plt.legend()
plt.show()
else:
plt.title("Accuracy Values")
plt.plot(model_name.history['accuracy'], label='train')
plt.plot(model_name.history['val_accuracy'], label='test')
plt.legend()
plt.show()
In [15]:
plot_metrics(history, 'accuracy')
plot_metrics(history, 'loss')
Making Predictions¶
In [16]:
prediction_loss, prediction_accuracy = model.evaluate(validation_images)
print("Prediction Accuracy: ", prediction_accuracy)
In [17]:
model = load_model('best_model.h5')
In [18]:
def predict(img_path, model):
image = load_img(img_path)
image = image.resize((64,64))
image = img_to_array(image)
image = np.expand_dims(image, axis = 0)
pred = model.predict(image)
#print(pred)
pred = np.argmax(pred)
if pred == 0:
return 'Apple Black Rot'
elif pred == 1:
return "Apple Cedar Rust"
else:
return "Apple Scab"
In [19]:
img_path = os.path.join (scab_path, random.choice(os.listdir(scab_path)))
#print(img_path)
prediction = predict(img_path, model)
pred = 'Prediction is ' + prediction
img = cv2.imread(img_path)
# Convert Image for BGR to RGB format
img = img[:,:, ::-1]
plt.imshow(img)
plt.grid(False)
plt.axis("off")
plt.title(pred)
plt.suptitle("Actual Disease : Apple Scab")
Out[19]: