-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcnn.py
More file actions
310 lines (258 loc) · 10.5 KB
/
Copy pathcnn.py
File metadata and controls
310 lines (258 loc) · 10.5 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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# import theano
import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
from keras.callbacks import TensorBoard
import time
import matplotlib.pyplot as plt
from keras.models import load_model
from data_frame_operations import DFOps
from tree_analysis import TreeData
'''
Much credit to Keras, their excellent documentation and thorough tutorials
----- https://keras.io/getting-started/sequential-model-guide/ -----
'''
class NeuralNetwork(object):
'''
This class will train neural network on image data
'''
def __init__(self):
'''
-- Initialize class --
'''
pass
def import_data(self,label_file_path,array_file_path,merge_on):
'''
-- Merge data into one array --
PARAMETERS
----------
label_file_path: str
File path to retrieve data containing filename, label in pickled pandas dataframe
array_file_path: str
File path to retrive data containing filename and numpy array's of pictures
merge_on: str
Column with pandas dataframe to merge on
RETURNS
-------
None
INITIALIZED
-----------
self.df:
Dataframe merged on 'merge_on'
'''
# pull data from arrays
df_arrays = pd.read_pickle(array_file_path)
df_labels = pd.read_pickle(label_file_path)
self.df_test_pics = pd.read_pickle('test.pkl')
self.test_array = self.df_test_pics['np_array']
self.test_array = np.array(list(self.test_array.values))
# merge df_arrays via left merge on merge_on
self.df = df_labels.merge(df_arrays,how='left',on=[merge_on])
def train_test_split(self,X_col_name,y_col_name,train_split):
'''
-- Merge data into one array --
PARAMETERS
----------
X_col_name: str
column name for X data
y_col_name: str
column name for y data
train_split: float -> 0.8
percent of data to be in train set
e.g. 80 percent train set, 20 percet test set
RETURNS
-------
None
INITIALIZED
-----------
self.X_train: np.array
array of pics to train on
self.X_test: np.array
array of pics to test on
self.y_train: np.array
array of labels to train on
self.y_test:
array of labels to test on
'''
# set X
X = self.df
# set y
y = self.df[y_col_name]
# split into train,test data
# keep data frame with all columns preserved for joining later
msk = np.random.rand(X.shape[0]) > train_split
self.X_train_all = X[~msk]
self.X_test_all = X[msk]
self.y_train = y[~msk]
self.y_test = y[msk]
# pull out np_array's from data frame
self.X_train = np.array(list(self.X_train_all[X_col_name].values))
self.X_test = np.array(list(self.X_test_all[X_col_name].values))
def set_parameters(self,
random_seed,
batch_size,
classes,
epochs,
image_dims,
num_filters,
pool,
kern_size,
colors):
'''
-- Set parameters for neural networks --
See below for instantiated attribues and step by step explanations
RETURNS
-------
None
INSTANTIATED
------------
See below
'''
# for reproducibility
np.random.seed(random_seed)
# see Keras documentation for explanations
self.batch_size = batch_size
self.nb_classes = classes
self.nb_epoch = epochs
# input image dimensions
img_rows, img_cols = image_dims[0], image_dims[1]
# number of convolutional filters to use
self.nb_filters = num_filters
# size of pooling area for max pooling
self.pool_size = pool
# convolution kernel size
self.kernel_size = kern_size
self.input_shape = (img_rows, img_cols, colors)
def run_models(self):
'''
-- Train network --
This method will need to be HARD CODED to edit model for training
See below for step by step process
'''
start = time.time()
# get data into correct format
X_train = self.X_train.astype('float32')
X_test = self.X_test.astype('float32')
# normalize
self.X_train_norm = X_train / 255
self.X_test_norm = X_test / 255
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(self.y_train, self.nb_classes)
Y_test = np_utils.to_categorical(self.y_test, self.nb_classes)
# set model
self.model = Sequential()
# 2 convolutional layers, followed by a pooling layer, followed by dropout, followed by classification
self.model.add(Convolution2D(10, 2, 2,
border_mode='valid',
input_shape=(100,50,3)))
self.model.add(Activation('relu'))
self.model.add(Convolution2D(10, 2, 2,
border_mode='valid',
input_shape=(100,50,3)))
self.model.add(Activation('relu'))
self.model.add(Convolution2D(10, 2, 2,
border_mode='valid',
input_shape=(100,50,3)))
self.model.add(Activation('relu'))
''' ----- '''
self.model.add(MaxPooling2D(pool_size=(2,2)))
self.model.add(Convolution2D(10, 2, 2,
border_mode='valid',
input_shape=(50,25,3)))
self.model.add(Activation('relu'))
self.model.add(Convolution2D(10, 2, 2,
border_mode='valid',
input_shape=(50,25,3)))
self.model.add(Activation('relu'))
self.model.add(Convolution2D(10, 2, 2,
border_mode='valid',
input_shape=(50,25,3)))
self.model.add(Activation('relu'))
''' ----- '''
self.model.add(MaxPooling2D(pool_size=(5,5)))
self.model.add(Convolution2D(25, 2, 2,
border_mode='valid',
input_shape=(10,5,3)))
self.model.add(Activation('relu'))
self.model.add(Convolution2D(25, 2, 2,
border_mode='valid',
input_shape=(10,5,3)))
self.model.add(Activation('relu'))
self.model.add(Convolution2D(25, 2, 2,
border_mode='valid',
input_shape=(10,5,3)))
self.model.add(Activation('relu'))
# transition to an mlp
self.model.add(Flatten())
self.model.add(Dense(200))
self.model.add(Activation('relu'))
self.model.add(Dropout(0.25))
self.model.add(Dense(self.nb_classes))
''' -- Classification -- '''
self.model.add(Activation('softmax'))
self.model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
tbCallBack = TensorBoard(log_dir='./graph',
histogram_freq=None,
write_graph=True,
write_images=True,
embeddings_metadata=True)
self.model.fit(self.X_train_norm, Y_train, batch_size=self.batch_size, epochs=self.nb_epoch,
verbose=1, validation_split=0.2,callbacks=[tbCallBack],
class_weight='auto')
# score model
self.score = self.model.evaluate(self.X_test_norm, Y_test, verbose=0)
end_time = time.time()-start
print('Test score:', self.score[0])
print('Test accuracy:', self.score[1])
print('Total time to run: {}'.format(int(end_time/60)))
# save model with accuracty and time
day = time.ctime().lower().replace(' ','_')
self.model.save('models/{}_{}'.format(round(self.score[1],4),day))
def output_predictions(self):
''' Get predictions based upon trained model for analysis '''
# predict classes on test data
predicted = self.model.predict_classes(self.X_test_norm)
predicted = predicted.tolist()
df_predicted = self.X_test_all
# add predicted test data to data frame
df_predicted['predicted'] = predicted
# drop np_arrays as they are large, unnecessary at this point and slow down computation
self.df_predicted = df_predicted.drop('np_array',axis=1)
# automatically save with time stamp
# set self.filename for using in tree_analysis.py Trees class
self.filename = 'data/predicted_{}.pkl'.format(time.ctime().replace(' ','_'))
df_predicted.to_pickle('{}'.format(self.filename))
if __name__ == '__main__':
NN = NeuralNetwork()
NN.import_data(label_file_path='data/balanced_data.pkl',
array_file_path='data/resized.pkl',
merge_on='filename')
NN.train_test_split(X_col_name='np_array',
y_col_name='label',
train_split=0.8)
NN.set_parameters(random_seed=17,
batch_size=100,
classes=2,
epochs=10,
image_dims=(100,50),
num_filters=3,
pool = (3, 3),
kern_size = (3, 3),
colors=3)
NN.run_models()
NN.output_predictions()
ops = DFOps(NN.filename)
ops.perform_all_ops()
ops.to_pickle(new_file_name='data/predicted_test_pipeline.pkl')
trees = TreeData('data/predicted_test_pipeline.pkl', 'data/all_labels.pkl')
trees.metric_by_block()
trees.metric_by_zip()
trees.get_all()
trees.tfRMSE()
trees.f1_score()