-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconvolutionNN.py
More file actions
171 lines (141 loc) · 6.19 KB
/
convolutionNN.py
File metadata and controls
171 lines (141 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#Convolution Neural Networks
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Activation, Dense, Flatten, BatchNormalization, Conv2D, MaxPool2D
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.metrics import categorical_crossentropy
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from sklearn.metrics import confusion_matrix
import itertools
import os
import shutil
import random
import glob
import matplotlib.pyplot as plt
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
#matplotlib inline
#Data preparation
#We are going to organizing our data into train, valid and test directories
os.chdir('data')
if os.path.isdir('train/dog') is False:
os.makedirs('train/dog')
os.makedirs('train/cat')
os.makedirs('valid/dog')
os.makedirs('valid/cat')
os.makedirs('test/dog')
os.makedirs('test/cat')
for c in random.sample(glob.glob('cat*'), 500):
shutil.move(c, 'train/cat')
for c in random.sample(glob.glob('dog*'), 500):
shutil.move(c, 'train/dog')
for c in random.sample(glob.glob('cat*'), 100):
shutil.move(c, 'valid/cat')
for c in random.sample(glob.glob('dog*'), 100):
shutil.move(c, 'valid/dog')
for c in random.sample(glob.glob('cat*'), 50):
shutil.move(c, 'test/cat')
for c in random.sample(glob.glob('dog*'), 50):
shutil.move(c, 'test/dog')
os.chdir('../')
#Now we will point our residing datasets to the variables
train_path = 'data/train'
valid_path = 'data/valid'
test_path = 'data/test'
#Now we need to put our data that the model expects. we now that when we train keras sequential model it recieves the data whenever we call the fit function
#We are going to put our images in the format of a keras generator
#We are creating three batches which is going to return a directory iterator from the directory where out dataset resides
#These batches of data will be used to train our model using fit function
train_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \
.flow_from_directory(directory=train_path, target_size=(224,224), classes=['cat', 'dog'], batch_size=10)
valid_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \
.flow_from_directory(directory=valid_path, target_size=(224,224), classes=['cat', 'dog'], batch_size=10)
test_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \
.flow_from_directory(directory=test_path, target_size=(224,224), classes=['cat', 'dog'], batch_size=10, shuffle=False)
#We dont have shuffled data for test set because we want to use it for inference using confusion matrix in the future
#Let us verify with an assert the three batches which we generated
assert train_batches.n == 1000
assert valid_batches.n == 200
assert test_batches.n == 100
assert train_batches.num_classes == valid_batches.num_classes == test_batches.num_classes == 2
#Next we are gonna grab single batch of images with corresponding labels
imgs, labels = next(train_batches)
#This function will plot images in the form of a grid with 1 row and 10 columns where images are placed
"""
def plotImages(images_arr):
fig, axes = plt.subplots(1, 10, figsize=(20, 20))
axes = axes.flatten()
for img, ax in zip( images_arr, axes ):
ax.imshow(img)
ax.axis('off')
plt.tight_layout()
plt.show()
plotImages(imgs)
"""
print(labels)
#Building and training CNN
model = Sequential([
Conv2D(filters=32, kernel_size=(3,3), activation='relu', padding='same',input_shape=(224,224,3)),
MaxPool2D(pool_size=(2,2), strides=2),
Conv2D(filters=64, kernel_size=(3,3), activation='relu', padding='same'),
MaxPool2D(pool_size=(2,2), strides=2),
Flatten(),
Dense(units=2, activation='softmax'),
])
model.summary()
model.compile(optimizer=Adam(learning_rate=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
#Here we do not need to specify 'y' in our fit function because we already have specified labels in our generator for
#'train_batches'. Usually 'y' is used in the function which has labelled data
model.fit(x=train_batches, validation_data=valid_batches, epochs=10, verbose=2)
#We see a huge difference between accuracy and val_accuracy it means that there is a problem of overfitting the data
#We will fine tune our model to overcome overfitting
#Predict
test_imgs, test_labels = next(test_batches)
#plotImages(test_imgs)
print(test_labels)
test_batches.classes
predictions = model.predict(x=test_batches, verbose=0)
import numpy as np
np.round(predictions)
cm = confusion_matrix(y_true=test_batches.classes, y_pred=np.argmax(predictions, axis=-1))
def plot_confusion_matrix(cm, classes,
normalize=False,
title='Confusion Matrix',
cmap=plt.cm.Blues):
"""
This function prints and plots the confusion matrix.
Normalization can be applied by setting 'normalize=True'.
:param cm:
:param classes:
:param normalize:
:param title:
:param cmap:
:return:
"""
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)
if normalize:
cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
print("Normalized confusion matrix")
else:
print("Confusion matrix without normalization")
print(cm)
thresh = cm.max() / 2.
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, cm[i, j],
horizontalalignment="center",
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label')
test_batches.class_indices
print("revt:test_batch class labels: ", test_batches.class_indices)
cm_plot_labels = ['cat', 'dog']
plot_confusion_matrix(cm=cm, classes=cm_plot_labels, title='Confusion Matrix')
vgg16_model = tf.keras.applications.vgg16.VGG16(weights='imagenet')
vgg16_model.summary()