-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.py
159 lines (123 loc) · 6.96 KB
/
model.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import numpy as np
from keras import layers
from keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D
from keras.models import Model, load_model
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras.applications.imagenet_utils import preprocess_input
import pydot
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
from keras.utils import plot_model
from Resnet_utils import *
from keras.initializers import glorot_uniform
import scipy.misc
from matplotlib.pyplot import imshow
import keras.backend as K
K.set_image_data_format('channels_last')
K.set_learning_phase(1)
def identity_block(X, f, filters , stage, block):
"""identity block implementation : Conv2D -> batchNorm -> Relu -> Conv2D -> batchNorm -> Relu -> Conv2D -> batchNorm ----> Add -> Relu
|--------------------------------------------------------------------------------->
X : input
f : filter size
filters : list specifying the number of filters in conv layers
stage and block : are used to define a location in the NN
"""
# defining name basis
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
F1, F2, F3 = filters
X_shortcut = X
# First component
X = Conv2D(filters = F1, kernel_size = (1, 1), strides = (1,1), padding = 'valid', name = conv_name_base + '2a', kernel_initializer = glorot_uniform(seed=0))(X)
X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)
X = Activation('relu')(X)
# Second component
X = Conv2D(filters = F2, kernel_size = (f,f), strides = (1,1), padding = "same", name = conv_name_base + '2b', kernel_initializer = glorot_uniform(seed = 0))(X)
X = BatchNormalization(axis = 3, name = bn_name_base + '2b')(X)
X = Activation('relu')(X)
# Third component
X = Conv2D(filters = F3, kernel_size = (1,1), strides = (1,1), padding = "same", name = conv_name_base + '2c', kernel_initializer = glorot_uniform(seed = 0))(X)
X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)
# Add shortcut value
X = Add()([X_shortcut,X])
X = Activation('relu')(X)
return X
def convolutional_block(X,f, filters, stage, block, s = 2):
"""convolutional block implementation : Conv2D -> batchNorm -> Relu -> Conv2D -> batchNorm -> Relu -> Conv2D -> batchNorm ----> Add -> Relu
|----------------------------------conv2D-> batchNorm ------------------------------>
X : input
f : filter size
filters : list specifying the number of filters in conv layers
stage and block : are used to define a location in the NN
"""
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
F1, F2, F3 = filters
X_shortcut = X
X = Conv2D(F1, (1, 1), strides = (s,s), name = conv_name_base + '2a', kernel_initializer = glorot_uniform(seed=0))(X)
X = BatchNormalization(axis = 3, name = bn_name_base + '2a')(X)
X = Activation('relu')(X)
X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding='same', name=conv_name_base + '2b', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2b')(X)
X = Activation('relu')(X)
X = Conv2D(filters = F3, kernel_size = (1,1), strides = (1,1), padding = 'valid', name = conv_name_base + '2c',kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis = 3, name = bn_name_base + '2c')(X)
X_shortcut = Conv2D(filters = F3, kernel_size = (1,1), strides = (s,s), padding = 'valid', name = conv_name_base + '1', kernel_initializer = glorot_uniform(seed = 0))(X_shortcut)
X_shortcut = BatchNormalization(axis = 3, name = bn_name_base + '1')(X_shortcut)
X = Add()([X,X_shortcut])
X = Activation('relu')(X)
return X
def ResNet50(input_shape = (64,64,3), classes = 6):
"""
Implementation of the ResNet50 the following architecture:
CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> CONVBLOCK -> IDBLOCK*2 -> CONVBLOCK -> IDBLOCK*3
-> CONVBLOCK -> IDBLOCK*5 -> CONVBLOCK -> IDBLOCK*2 -> AVGPOOL -> TOPLAYER
"""
X_input = Input(input_shape)
X = ZeroPadding2D((3, 3))(X_input)
# Stage 1
X = Conv2D(64, (7, 7), strides = (2, 2), name = 'conv1', kernel_initializer = glorot_uniform(seed=0))(X)
X = BatchNormalization(axis = 3, name = 'bn_conv1')(X)
X = Activation('relu')(X)
X = MaxPooling2D((3, 3), strides=(2, 2))(X)
# Stage 2
X = convolutional_block(X, f = 3, filters = [64, 64, 256], stage = 2, block='a', s = 1)
X = identity_block(X, 3, [64, 64, 256], stage=2, block='b')
X = identity_block(X, 3, [64, 64, 256], stage=2, block='c')
# Stage 3 (≈4 lines)
X = convolutional_block(X, f = 3, filters = [128,128,512], stage = 3, block = 'a', s = 2)
X = identity_block(X, f = 3, filters = [128,128,512], stage = 3, block = 'b')
X = identity_block(X, f = 3, filters = [128,128,512], stage = 3, block = 'c')
X = identity_block(X, f = 3, filters = [128,128,512], stage = 3, block = 'd')
# Stage 4 (≈6 lines)
X = convolutional_block(X, f = 3, filters = [256,256,1024], stage = 4, block = 'a', s = 2)
X = identity_block(X, f = 3, filters = [256,256,1024], stage = 4, block = 'b')
X = identity_block(X, f = 3, filters = [256,256,1024], stage = 4, block = 'c')
X = identity_block(X, f = 3, filters = [256,256,1024], stage = 4, block = 'd')
X = identity_block(X, f = 3, filters = [256,256,1024], stage = 4, block = 'e')
X = identity_block(X, f = 3, filters = [256,256,1024], stage = 4, block = 'f')
# Stage 5 (≈3 lines)
X = convolutional_block(X,f = 3 , filters = [512, 512, 2048], stage = 5, block = 'a',s = 2 )
X = identity_block(X, f = 3, filters = [512, 512, 2048], stage = 5, block = 'b')
X = identity_block(X, f = 3, filters = [512, 512, 2048], stage = 5, block = 'c')
X = AveragePooling2D(pool_size = (2,2), padding = "same")(X)
X = Flatten()(X)
X = Dense(classes, activation='softmax', name='fc' + str(classes), kernel_initializer = glorot_uniform(seed=0))(X)
model = Model(inputs = X_input, outputs = X, name='ResNet50')
return model
model = ResNet50(input_shape = (64, 64, 3), classes = 6)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()
# Normalize image vectors
X_train = X_train_orig/255.
X_test = X_test_orig/255.
Y_train = convert_to_one_hot(Y_train_orig, 6).T
Y_test = convert_to_one_hot(Y_test_orig, 6).T
model.fit(X_train, Y_train, epochs = 2, batch_size = 32) #trained it only for 2 epochs but it should be more for better accuracy
preds = model.evaluate(X_test, Y_test)
preds = model.evaluate(X_test, Y_test)
print ("Loss = " + str(preds[0]))
print ("Test Accuracy = " + str(preds[1]))