-
Notifications
You must be signed in to change notification settings - Fork 47
/
cnn_major_shallow.py
144 lines (113 loc) · 4.21 KB
/
cnn_major_shallow.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
from __future__ import print_function
import numpy as np
# get the data
filname = 'fer2013.csv'
label_map = ['Anger', 'Disgust', 'Fear', 'Happy', 'Sad', 'Surprise', 'Neutral']
def getData(filname):
# images are 48x48
# N = 35887
Y = []
X = []
first = True
for line in open(filname):
if first:
first = False
else:
row = line.split(',')
Y.append(int(row[0]))
X.append([int(p) for p in row[1].split()])
X, Y = np.array(X) / 255.0, np.array(Y)
return X, Y
X, Y = getData(filname)
num_class = len(set(Y))
# To see number of training data point available for each label
def balance_class(Y):
num_class = set(Y)
count_class = {}
for i in range(len(num_class)):
count_class[i] = sum([1 for y in Y if y == i])
return count_class
balance = balance_class(Y)
# keras with tensorflow backend
N, D = X.shape
X = X.reshape(N, 48, 48, 1)
# Split in training set : validation set : testing set in 80:10:10
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.1, random_state=0)
y_train = (np.arange(num_class) == y_train[:, None]).astype(np.float32)
y_test = (np.arange(num_class) == y_test[:, None]).astype(np.float32)
from keras.models import Sequential
from keras.layers import Dense , Activation , Dropout ,Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.metrics import categorical_accuracy
from keras.models import model_from_json
from keras.optimizers import *
from keras.layers.normalization import BatchNormalization
batch_size = 128
epochs = 15
#Shallow CNN model with two Convolution layer & one fully connected layer
def baseline_model():
# Initialising the CNN
model = Sequential()
# 1 - Convolution
model.add(Conv2D(64,(3,3), border_mode='same', input_shape=(48, 48,1)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# 2nd Convolution layer
model.add(Conv2D(128,(5,5), border_mode='same'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# Flattening
model.add(Flatten())
# Fully connected layer 1st layer
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(num_class, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[categorical_accuracy])
return model
def baseline_model_saved():
#load json and create model
json_file = open('model_2layer_2_2_pool.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
model = model_from_json(loaded_model_json)
#load weights from h5 file
model.load_weights("model_2layer_2_2_pool.h5")
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[categorical_accuracy])
return model
is_model_saved = True
# If model is not saved train the CNN model otherwise just load the weights
if(is_model_saved==False ):
# Train model
model = baseline_model()
# Note : 3259 samples is used as validation data & 28,709 as training samples
model.fit(X_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=2,
validation_split=0.1111)
model_json = model.to_json()
with open("model_2layer_2_2_pool.json", "w") as json_file:
json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("model_2layer_2_2_pool.h5")
print("Saved model to disk")
else:
# Load the trained model
print("Load model from disk")
model = baseline_model_saved()
# Model will predict the probability values for 7 labels for a test image
score = model.predict(X_test)
print (model.summary())
new_X = [ np.argmax(item) for item in score ]
y_test2 = [ np.argmax(item) for item in y_test]
# Calculating categorical accuracy taking label having highest probability
accuracy = [ (x==y) for x,y in zip(new_X,y_test2) ]
print(" Accuracy on Test set : " , np.mean(accuracy))