In [1]:
!wget https://cainvas-static.s3.amazonaws.com/media/user_data/Rodio346/Sheep_Dataset.zip
In [2]:
!unzip -qo "Sheep_Dataset.zip"
In [3]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers, callbacks, optimizers
from sklearn.metrics import confusion_matrix, f1_score
from tensorflow import keras
import os, shutil
import random
from PIL import Image
import cv2
Looking at the Dataset¶
In [4]:
img = Image.open("Sheep Dataset/Yes/17.jpg")
In [5]:
plt.imshow(img)
Out[5]:
In [6]:
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import cv2
import imutils
import matplotlib.pyplot as plt
from os import listdir
import time
Applying data Augmentation¶
In [7]:
def augment_data(file_dir, n_generated_samples, save_to_dir):
"""
Arguments:
file_dir: A string representing the directory where images that we want to augment are found.
n_generated_samples: A string representing the number of generated samples using the given image.
save_to_dir: A string representing the directory in which the generated images will be saved.
"""
#from keras.preprocessing.image import ImageDataGenerator
#from os import listdir
data_gen = ImageDataGenerator(rotation_range=10,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.1,
brightness_range=(0.3, 1.0),
horizontal_flip=True,
vertical_flip=True,
fill_mode='nearest'
)
for filename in listdir(file_dir):
# load the image
if filename ==".ipynb_checkpoints":
continue
image = cv2.imread(file_dir +'/' + filename)
# reshape the image
image = cv2.resize(image,(240,240))
image = image.reshape((1,)+image.shape)
# prefix of the names for the generated sampels.
save_prefix = 'aug_' + filename[:-4]
# generate 'n_generated_samples' sample images
i=0
for batch in data_gen.flow(x=image, batch_size=1, save_to_dir=save_to_dir,
save_prefix=save_prefix, save_format='jpg'):
i += 1
if i > n_generated_samples:
break
In [8]:
data_dir = 'Sheep Dataset/'
batch_size = 64
# image_size = (32, 32)
image_size = (240, 240)
print("Training set")
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
color_mode="grayscale",
image_size=image_size,
seed=113,
shuffle=True,
batch_size=batch_size
)
print("Validation set")
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="validation",
color_mode="grayscale",
image_size=image_size,
seed=113,
shuffle=True,
batch_size=batch_size
)
In [9]:
class_names = train_ds.class_names
print(class_names)
In [10]:
Xtrain = np.empty((0,*image_size,1))
ytrain = np.empty((0,1))
for x in train_ds.enumerate():
for y in x[1][0]:
Xtrain = np.append(Xtrain, np.expand_dims(np.array(y),0), axis = 0)
#print(Xtrain.shape)
ytrain = np.append(ytrain, np.array(x[1][1]))
#print(ytrain.shape)
Xtrain.shape, ytrain.shape
Out[10]:
In [11]:
print("Number of samples - ")
for i in range(len(class_names)):
print(class_names[i], "-", ytrain.tolist().count(float(i)))
In [12]:
data_augmentation = tf.keras.Sequential(
[
layers.experimental.preprocessing.RandomFlip("horizontal"), # Flip along vertical axes
layers.experimental.preprocessing.RandomZoom(0.1), # Randomly zoom images in dataset
])
print("Train size (number of samples) before augmentation: ", len(Xtrain))
aug_sample_count = ytrain.tolist().count(float(0.0))//2 - ytrain.tolist().count(float(1.0))
cur_augmented = 0
# Apply only to train set
while(cur_augmented!=aug_sample_count):
for i in range(len(Xtrain)):
if ytrain[i] == 1: # not elephant
aug_image = np.array(data_augmentation(np.expand_dims(Xtrain[0], 0)))
Xtrain = np.append(Xtrain, aug_image.reshape((1, *image_size, 1)), axis = 0)
ytrain = np.append(ytrain, [1])
cur_augmented += 1
if (cur_augmented == aug_sample_count):
break
print("Size (number of samples) of final dataset: ", len(Xtrain))
print(" Dataset shapes: ", Xtrain.shape, ytrain.shape)
In [13]:
print("Number of samples - ")
for i in range(len(class_names)):
print(class_names[i], "-", ytrain.tolist().count(float(i)))
In [14]:
Xval = np.empty((0,*image_size,1))
yval = np.empty((0,1))
for x in val_ds.enumerate():
for y in x[1][0]:
Xval = np.append(Xval, np.expand_dims(np.array(y),0), axis = 0)
#print(Xtrain.shape)
yval = np.append(yval, np.array(x[1][1]))
#print(ytrain.shape)
Xval.shape, yval.shape
Out[14]:
In [15]:
print("Number of samples - ")
for i in range(len(class_names)):
print(class_names[i], "-", yval.tolist().count(float(i)))
Visulatizing Samples¶
In [16]:
num_samples = 4 # the number of samples to be displayed in each class
for x in class_names:
plt.figure(figsize=(10, 10))
filenames = os.listdir(data_dir + x)
for i in range(num_samples):
ax = plt.subplot(1, num_samples, i + 1)
img = Image.open(os.path.join(data_dir, x, filenames[i]))
plt.imshow(img)
plt.title(x)
plt.axis("off")
In [17]:
Xtrain = Xtrain/255
Xval = Xval/255
Model¶
In [21]:
model = keras.models.Sequential([
layers.Conv2D(8, 3, activation='relu', input_shape=Xtrain[0].shape),
layers.MaxPool2D(pool_size=(2, 2)),
layers.Conv2D(16, 3, activation='relu'),
layers.MaxPool2D(pool_size=(2, 2)),
layers.Conv2D(32, 3, activation='relu'),
layers.MaxPool2D(pool_size=(2, 2)),
layers.Conv2D(32, 3, activation='relu'),
layers.MaxPool2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dense(32, activation='relu'),
layers.Dense(1, activation='sigmoid')
])
cb = [callbacks.EarlyStopping(monitor = 'val_loss', patience = 5, restore_best_weights = True)]
In [22]:
model.summary()
In [23]:
model.compile(loss=keras.losses.BinaryCrossentropy(), optimizer=optimizers.Adam(0.0001), metrics=['accuracy'])
history = model.fit(Xtrain, ytrain, validation_data=(Xval, yval), epochs=300, callbacks=cb)
In [24]:
model.evaluate(Xval, yval)
Out[24]:
In [25]:
ypred = (model.predict(Xval)>0.5).astype('int')
In [26]:
cm = confusion_matrix(yval, ypred)
cm = cm.astype('int') / cm.sum(axis=1)[:, np.newaxis]
fig = plt.figure(figsize = (4, 4))
ax = fig.add_subplot(111)
for i in range(cm.shape[1]):
for j in range(cm.shape[0]):
if cm[i,j] > 0.8:
clr = "white"
else:
clr = "black"
ax.text(j, i, format(cm[i, j], '.2f'), horizontalalignment="center", color=clr)
_ = ax.imshow(cm, cmap=plt.cm.Blues)
ax.set_xticks(range(len(class_names)))
ax.set_yticks(range(len(class_names)))
ax.set_xticklabels(class_names, rotation = 90)
ax.set_yticklabels(class_names)
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()
In [27]:
f1_score(yval, ypred, average = 'binary')
Out[27]:
In [28]:
def plot(history, variable1, variable2):
plt.plot(range(len(history[variable1])), history[variable1])
plt.plot(range(len(history[variable2])), history[variable2])
plt.legend([variable1, variable2])
plt.title(variable1)
Result¶
In [29]:
plot(history.history, "accuracy", 'val_accuracy')
Predcition¶
In [30]:
x = random.randint(0, 32 - 1) # default batch size is 32
for i in val_ds.as_numpy_iterator():
img, label = i
plt.axis('off') # remove axes
plt.imshow(img[x]) # shape from (64, 64, 64, 1) --> (64, 64, 1)
output = model.predict(np.expand_dims(img[x],0))[0][0] # getting output; input shape (64, 64, 3) --> (1, 64, 64, 1)
pred = (output > 0.5).astype('int')
print("Predicted: ", class_names[pred], '(', output, '-->', pred, ')') # Picking the label from class_names base don the model output
print("True: ", class_names[label[x]])
break
In [33]:
model.save("Sheep_detection.h5")
DeepCC¶
In [ ]:
!deepCC Sheep_detection.h5