Tags:
flora
plants
Flower
petals
Similar Use Cases: Flower Detection App Fruits Classification App Tomato Disease Detection App Potato Weed Plant Detection App
Similar Use Cases: Flower Detection App Fruits Classification App Tomato Disease Detection App Potato Weed Plant Detection App
Unzip Data¶
In [1]:
!wget https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/Flower_Color.zip
In [2]:
!unzip -qo Flower_Color.zip
Import Libraries¶
In [3]:
import numpy as np
import pandas as pd
from PIL import ImageFile
from tqdm import tqdm
import h5py
import cv2
import matplotlib.pylab as plt
from matplotlib import cm
%matplotlib inline
from sklearn.model_selection import train_test_split
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing import image as keras_image
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import Dense, LSTM, GlobalAveragePooling1D, GlobalAveragePooling2D
from tensorflow.keras.layers import Activation, Flatten, Dropout, BatchNormalization
from tensorflow.keras.layers import Conv2D, MaxPooling2D, GlobalMaxPooling2D
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
from tensorflow.keras.layers import PReLU, LeakyReLU
from sklearn.metrics import confusion_matrix
from sklearn.metrics import plot_confusion_matrix
import seaborn as sns
Data Preprocessing¶
Load image and convert into array¶
In [4]:
def image_to_tensor(img_path):
img = keras_image.load_img("Flower Color/flower_images/" + img_path, target_size=(128, 128))
x = keras_image.img_to_array(img)
return np.expand_dims(x, axis=0)
Convert images into tensors¶
In [5]:
def data_to_tensor(img_paths):
list_of_tensors = [image_to_tensor(img_path) for img_path in tqdm(img_paths)]
return np.vstack(list_of_tensors)
Load the data¶
In [6]:
ImageFile.LOAD_TRUNCATED_IMAGES = True
# Load the data
data = pd.read_csv("Flower Color/flower_images/flower_labels.csv")
files = data['file']
targets = data['label'].values
tensors = data_to_tensor(files);
In [7]:
data.head()
Out[7]:
In [8]:
tensors.shape
Out[8]:
In [9]:
targets.shape
Out[9]:
In [10]:
# Name list
names = ['phlox', 'rose', 'calendula', 'iris', 'max chrysanthemum',
'bellflower', 'viola', 'rudbeckia laciniata', 'peony', 'aquilegia']
Display sample images¶
In [11]:
def display_images(img_path, ax):
img = cv2.imread("Flower Color/flower_images/" + img_path)
ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
In [12]:
fig = plt.figure(figsize=(20, 10))
for i in range(4):
ax = fig.add_subplot(2, 4, i + 1, xticks=[], yticks=[])
ax.set_title(names[targets[i+10]], color='yellow')
display_images(files[i+10], ax)
Save data in h5 file for future use¶
In [13]:
# Create h5 file and save data
with h5py.File('FlowerColorImages.h5', 'w') as f:
f.create_dataset('images', data = tensors)
f.create_dataset('labels', data = targets)
f.close()
In [14]:
# Read the h5 file
f = h5py.File('FlowerColorImages.h5', 'r')
# List all groups
keys = list(f.keys())
keys
Out[14]:
Create tensors and targets¶
In [15]:
tensors = np.array(f[keys[0]])
targets = np.array(f[keys[1]])
print ('Tensor shape:', tensors.shape)
print ('Target shape', targets.shape)
In [16]:
# Create a csv file and save data
images_csv = tensors.reshape(210,128*128*3)
np.savetxt("flower_images.csv", images_csv, fmt='%i', delimiter=",")
In [17]:
# Read the pandas dataframe from csv
data_images = pd.read_csv("flower_images.csv", header=None)
data_images.head()
Out[17]:
In [18]:
data_images.iloc[:10,:10]
Out[18]:
In [19]:
data_images.shape
Out[19]:
In [20]:
# Read image tensors from the dataframe
tensors = data_images.values
tensors.shape
Out[20]:
In [21]:
tensors = tensors.reshape(-1,128,128,3)
tensors.shape
Out[21]:
Normalize the tensors¶
In [22]:
tensors = tensors.astype('float32')/255
One-hot encode the targets¶
In [23]:
targets = to_categorical(targets, 10)
Split the data¶
In [24]:
x_train, x_test, y_train, y_test = train_test_split(tensors, targets,
test_size = 0.2,
random_state = 1)
n = int(len(x_test)/2)
x_valid, y_valid = x_test[:n], y_test[:n]
x_test, y_test = x_test[n:], y_test[n:]
In [25]:
x_train.shape, y_train.shape
Out[25]:
In [26]:
x_test.shape, y_test.shape
Out[26]:
In [27]:
x_valid.shape, y_valid.shape
Out[27]:
In [28]:
# Read and display a tensor
print('Label: ', names[np.argmax(y_train[7])])
plt.figure(figsize=(3,3))
plt.imshow((x_train[7]));
Define Model and Train¶
Define the model¶
In [29]:
def model():
model = Sequential()
model.add(Conv2D(128, (3, 3), input_shape=x_train.shape[1:]))
model.add(LeakyReLU(alpha=0.02))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3, 3)))
model.add(LeakyReLU(alpha=0.02))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(GlobalMaxPooling2D())
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.02))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))
# TODO: Compile the model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
model = model()
Create callbacks¶
In [30]:
# To save the best model
checkpointer = ModelCheckpoint(filepath='weights.best.model.hdf5',
verbose=2, save_best_only=True)
# To reduce learning rate dynamically
lr_reduction = ReduceLROnPlateau(monitor='val_loss',
patience=5, verbose=2, factor=0.2)
In [31]:
model.summary()
Train the model¶
In [32]:
history = model.fit(x_train, y_train,
epochs=75, batch_size=32, verbose=2,
validation_data=(x_valid, y_valid),
callbacks=[checkpointer,lr_reduction])
Train the model with image generation¶
In [33]:
data_generator = keras_image.ImageDataGenerator(shear_range=0.3,
zoom_range=0.3,
rotation_range=30,
horizontal_flip=True)
dg_history = model.fit_generator(data_generator.flow(x_train, y_train, batch_size=64),
steps_per_epoch = len(x_train)//64, epochs=7, verbose=2,
validation_data=(x_valid, y_valid),
callbacks=[checkpointer,lr_reduction])
In [34]:
# Load the model with the best validation accuracy
model.load_weights('weights.best.model.hdf5')
Model Evaluation¶
In [36]:
# Calculate classification accuracy on the testing set
score = model.evaluate(x_test, y_test)
score
Out[36]:
In [38]:
# Calculate classification accuracy on the training set
score = model.evaluate(x_train, y_train)
score
Out[38]:
In [40]:
# Calculate classification accuracy on the validation set
score = model.evaluate(x_valid, y_valid)
score
Out[40]:
Accuracy Plot¶
In [41]:
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
Loss Plot¶
In [42]:
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper right')
plt.show()
In [43]:
model.save('model.h5')
In [44]:
model1 = load_model('model.h5')
Predictions¶
In [45]:
# Model predictions for the testing dataset
y_test_predict = model1.predict(x_test)
In [46]:
y_test_predict = np.argmax(y_test_predict,axis=1)
Display Predictions¶
In [47]:
# Display true labels and predictions
fig = plt.figure(figsize=(18, 18))
for i, idx in enumerate(np.random.choice(x_test.shape[0], size=16, replace=False)):
ax = fig.add_subplot(4, 4, i + 1, xticks=[], yticks=[])
ax.imshow(np.squeeze(x_test[idx]))
pred_idx = y_test_predict[idx]
true_idx = np.argmax(y_test[idx])
ax.set_title("{} ({})".format(names[pred_idx], names[true_idx]),
color=("#4876ff" if pred_idx == true_idx else "darkred"))