-
Notifications
You must be signed in to change notification settings - Fork 0
/
cnn.py
138 lines (104 loc) · 3.93 KB
/
cnn.py
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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 19 18:28:40 2018
@author: KaranJaisingh
"""
# import required libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from imutils import paths
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout
from keras.applications import VGG19
from keras.models import Model
from keras.callbacks import EarlyStopping
from keras.optimizers import SGD
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
# override truncated images error
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
# define constants and parameters
train_data_dir = "train"
test_data_dir = "test"
TRAIN = len(list(paths.list_images(train_data_dir)))
TEST = len(list(paths.list_images(test_data_dir)))
BS = 10
EPOCHS = 2
img_width, img_height = 300, 300
# create model skeleton
base_model = VGG19(weights = "imagenet", include_top=False,
input_shape = (img_width, img_height, 3))
x = base_model.output
x = Flatten()(x)
x = Dense(1024, activation = "relu")(x)
x = Dropout(0.4)(x)
x = Dense(256, activation = "relu")(x)
x = Dropout(0.1)(x)
preds = Dense(2, activation = "softmax")(x)
model = Model(input = base_model.input, output = preds)
for i,layer in enumerate(model.layers):
print(i,layer.name)
for layer in model.layers[:14]:
layer.trainable=False
for layer in model.layers[14:]:
layer.trainable=True
model.summary()
# compile model
early = EarlyStopping(monitor = 'val_acc', min_delta = 0,
patience = 10, verbose= 1 , mode = 'auto')
model.compile(loss = "binary_crossentropy",
optimizer = SGD(lr=0.001, momentum=0.9),
metrics=["accuracy"])
# create data generators and data pathways
from keras.preprocessing.image import ImageDataGenerator
trainAug = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = "nearest")
testAug = ImageDataGenerator(rescale = 1./255,
fill_mode = "nearest")
trainGen = trainAug.flow_from_directory('train',
target_size = (img_width, img_height),
batch_size = BS,
shuffle = True,
class_mode = 'categorical')
testGen = testAug.flow_from_directory('test',
target_size = (img_width, img_height),
batch_size = BS,
class_mode = 'categorical')
# train model
classes = trainGen.class_indices
print(classes)
H = model.fit_generator(trainGen, epochs = EPOCHS,
steps_per_epoch = TRAIN // BS)
print("CNN Trained")
# save model
model.save('model.h5')
print("CNN Saved")
# plotting training data
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, EPOCHS), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, EPOCHS), H.history["accuracy"], label="train_acc")
plt.title("Training Loss and Accuracy on Dataset")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig("plot.jpg")
# generating predictions using model
testGen.reset()
predictions = model.predict_generator(testGen, steps = (TEST // BS) + 1)
predictions = np.argmax(predictions, axis=1)
# evaluating predictions
acc = str(round(accuracy_score(testGen.classes, predictions, normalize=True) * 100, 2))
print("Test set accuracy: " + acc + "%")
print("Classification report: \n" + classification_report(testGen.classes, predictions,
target_names=testGen.class_indices.keys()))