@@ -124,7 +124,7 @@ def plot_cm(model, Xval, Yval, val_map, title):
124
124
df_cm = pd .DataFrame (cm / np .sum (cm ), index = [val_map [i ] for i in range (len (set (Yval )))],
125
125
columns = [val_map [i ] for i in range (len (set (Yval )))])
126
126
127
- # plt.figure(fig_size = (10, 7))
127
+ plt .figure (figsize = (10 , 7 ))
128
128
sns .heatmap (df_cm , annot = True , fmt = '.2%' )
129
129
plt .title (title )
130
130
plt .show ()
@@ -173,6 +173,10 @@ def train_model(model, args, label = 'gender'):
173
173
loss = args ['loss' ], metrics = ['accuracy' ]
174
174
)
175
175
176
+ print (model .summary ())
177
+
178
+ keras .utils .plot_model (model , str (args ['task_number' ])+ '_' + label + '.png' , show_shapes = True )
179
+
176
180
# Fit the model
177
181
history = model .fit (
178
182
Xtrain , Ytrain ,
@@ -190,31 +194,28 @@ def train_model(model, args, label = 'gender'):
190
194
plt .legend ()
191
195
plt .show ()
192
196
193
- plot_cm (model , Xval , Yval , val_map , title = 'Task {}, Label = {} Validation Confusion Matrix' .format (args ['task_number' ], label ))
197
+ plot_cm (model , Xval , Yval , val_map , title = 'Task {}, {} Validation Confusion Matrix' .format (args ['task_number' ], label ))
194
198
195
199
def evoke_task (task_number = 'task1' , label = 'gender' ):
196
- '''
197
- Evokes the given task number from the command line
200
+ """Evokes the given task number from the command line
198
201
- Parsing done in if main statement
199
-
200
- Arguments:
201
- ----------
202
202
203
- Returns:
204
- --------
205
- '''
203
+ Args:
204
+ task_number (str, optional): which task to run. Defaults to 'task1'.
205
+ label (str, optional): which attribute to classify. Defaults to 'gender'.
206
+ """
206
207
207
208
if task_number == 'task1' :
208
209
209
210
if label == 'gender' :
210
211
l = 'binary_crossentropy'
211
- eps = 13
212
+ eps = 50
212
213
elif label == 'age' :
213
214
l = tf .keras .losses .SparseCategoricalCrossentropy ()
214
- eps = 11
215
+ eps = 50
215
216
elif label == 'race' :
216
217
l = tf .keras .losses .SparseCategoricalCrossentropy ()
217
- eps = 11
218
+ eps = 50
218
219
219
220
model = tf .keras .Sequential ()
220
221
model .add (keras .Input (shape = (32 ,32 , 1 )))
@@ -260,32 +261,49 @@ def evoke_task(task_number = 'task1', label = 'gender'):
260
261
261
262
if label == 'gender' :
262
263
l = 'binary_crossentropy'
263
- eps = 13
264
+ eps = 50
265
+ lr = 0.01
264
266
elif label == 'age' :
265
267
l = tf .keras .losses .SparseCategoricalCrossentropy ()
266
- eps = 11
268
+ eps = 50
269
+ lr = 0.1
267
270
elif label == 'race' :
268
271
l = tf .keras .losses .SparseCategoricalCrossentropy ()
269
- eps = 11
272
+ eps = 50
273
+ lr = 0.01
270
274
271
275
model = tf .keras .Sequential ()
272
- model .add (layers .Conv2D (filters = 40 , kernel_size = 3 , activation = 'relu' , strides = 1 , input_shape = (32 , 32 , 1 ), padding = 'valid' ))
273
- model .add (layers .Conv2D (filters = 80 , kernel_size = 5 , activation = 'relu' , strides = 1 , padding = 'valid' ))
276
+ model .add (layers .Conv2D (filters = 64 , kernel_size = 3 , activation = 'relu' , strides = 1 , input_shape = (32 , 32 , 1 ), padding = 'same' ))
277
+ model .add (layers .Conv2D (filters = 64 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' ))
278
+ model .add (layers .Conv2D (filters = 64 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' ))
274
279
model .add (layers .MaxPooling2D (2 ))
280
+ #model.add(layers.Dropout(rate=0.5))
281
+ model .add (layers .Conv2D (filters = 128 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' ))
282
+ model .add (layers .Conv2D (filters = 128 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' ))
283
+ model .add (layers .Conv2D (filters = 128 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' ))
284
+ model .add (layers .MaxPooling2D (2 ))
285
+ model .add (layers .Dropout (rate = 0.5 ))
286
+ model .add (layers .Conv2D (filters = 256 , kernel_size = 2 , activation = 'relu' , strides = 1 , padding = 'same' ))
287
+ model .add (layers .Conv2D (filters = 256 , kernel_size = 2 , activation = 'relu' , strides = 1 , padding = 'same' ))
288
+ model .add (layers .Conv2D (filters = 256 , kernel_size = 2 , activation = 'relu' , strides = 1 , padding = 'same' ))
289
+ model .add (layers .MaxPooling2D (2 ))
290
+ #model.add(layers.Dropout(rate=0.5))
275
291
model .add (layers .Flatten ())
276
- model .add (layers .Dense (1000 , activation = 'relu' ))
292
+ model .add (layers .Dense (4096 , activation = 'relu' ))
293
+ model .add (layers .Dense (1024 , activation = 'relu' ))
294
+ model .add (layers .Dense (1024 , activation = 'relu' ))
277
295
278
296
args = {
279
297
'loss' : l ,
280
- 'optimizer' : tf .keras .optimizers .SGD (learning_rate = 0.1 ),
281
- 'epochs' : eps ,
298
+ 'optimizer' : tf .keras .optimizers .SGD (learning_rate = lr ),
299
+ 'epochs' : 50 ,
282
300
'batch_size' : 128 ,
283
301
'task_number' : 3
284
302
}
285
303
286
304
train_model (model , args , label )
287
305
288
- def task4 (label = ['gender' , 'age' ]):
306
+ def task4 (label = ['gender' ,'age' ]):
289
307
'''
290
308
Runs task 4
291
309
Note: this function does not perform advanced preprocessing other than loading data
@@ -295,14 +313,9 @@ def task4(label = ['gender', 'age']):
295
313
296
314
Arguments:
297
315
----------
298
- model: keras model instance
299
- - Built model (not trained)
300
- args: dictionary
301
- - Should contain values with keys:
302
- 'optimizer', 'loss', 'epochs', 'batch_size', 'task_number'
303
- label: string, optional
304
- - Default: 'gender'
305
- - Label you're trying to predict
316
+ label: list
317
+ - Default: ['gender', 'age']
318
+ - Labels you're trying to predict
306
319
307
320
Returns:
308
321
--------
@@ -313,6 +326,7 @@ def task4(label = ['gender', 'age']):
313
326
Xtrain , train_labels , Xval , val_labels = load_data ()
314
327
315
328
l = []
329
+ l_wts = []
316
330
Ytrain = []
317
331
Yval = []
318
332
num_classes = []
@@ -326,37 +340,66 @@ def task4(label = ['gender', 'age']):
326
340
Yval .append (val_dat )
327
341
if i == 'gender' :
328
342
l .append ('binary_crossentropy' )
343
+ l_wts .append (0.1 )
329
344
elif i == 'age' :
330
345
l .append (tf .keras .losses .SparseCategoricalCrossentropy ())
346
+ l_wts .append (4.0 )
331
347
elif i == 'race' :
332
348
l .append (tf .keras .losses .SparseCategoricalCrossentropy ())
349
+ l_wts .append (1.0 )
333
350
334
- eps = 30
351
+ eps = 50
335
352
336
353
image_input = tf .keras .Input (shape = (32 ,32 ,1 ))
337
- h1 = layers .Conv2D (filters = 40 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'valid' )(image_input )
338
- h2 = layers .Conv2D (filters = 80 , kernel_size = 5 , activation = 'relu' , strides = 1 , padding = 'valid' )(h1 )
339
- flatten = layers .Flatten ()(h2 )
340
- last_hidden = layers .Dense (1000 , activation = 'relu' )(flatten )
354
+ c1 = layers .Conv2D (filters = 64 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' )(image_input )
355
+ c2 = layers .Conv2D (filters = 64 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' )(c1 )
356
+ c3 = layers .Conv2D (filters = 64 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' )(c2 )
357
+ bn1 = layers .BatchNormalization ()(c3 )
358
+ m1 = layers .MaxPooling2D (2 )(bn1 )
359
+ d1 = layers .Dropout (rate = 0.25 )(m1 )
360
+ c4 = layers .Conv2D (filters = 128 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' )(d1 )
361
+ c5 = layers .Conv2D (filters = 128 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' )(c4 )
362
+ c6 = layers .Conv2D (filters = 128 , kernel_size = 3 , activation = 'relu' , strides = 1 , padding = 'same' )(c5 )
363
+ bn2 = layers .BatchNormalization ()(c6 )
364
+ m2 = layers .MaxPooling2D (2 )(bn2 )
365
+ d2 = layers .Dropout (rate = 0.25 )(m2 )
366
+ c7 = layers .Conv2D (filters = 256 , kernel_size = 2 , activation = 'relu' , strides = 1 , padding = 'same' )(d2 )
367
+ c8 = layers .Conv2D (filters = 256 , kernel_size = 2 , activation = 'relu' , strides = 1 , padding = 'same' )(c7 )
368
+ c9 = layers .Conv2D (filters = 256 , kernel_size = 2 , activation = 'relu' , strides = 1 , padding = 'same' )(c8 )
369
+ m3 = layers .MaxPooling2D (2 )(c9 )
370
+ d3 = layers .Dropout (rate = 0.25 )(m3 )
371
+ flatten = layers .Flatten ()(d3 )
341
372
342
373
output_layers = []
343
374
for i in range (len (label )):
344
375
if label [i ] == 'gender' :
345
- output_layers .append (layers .Dense (num_classes [i ], name = 'gender' )(last_hidden ))
376
+ g1 = layers .Dense (4096 , activation = 'relu' )(flatten )
377
+ g2 = layers .Dense (2048 , activation = 'relu' )(g1 )
378
+
379
+ output_layers .append (layers .Dense (num_classes [i ]- 1 , name = 'gender' , activation = 'sigmoid' )(g2 ))
346
380
elif label [i ] == 'age' :
347
- output_layers .append (layers .Dense (num_classes [i ], name = 'age' )(last_hidden ))
381
+ a1 = layers .Dense (4096 , activation = 'relu' )(flatten )
382
+ a2 = layers .Dense (2048 , activation = 'relu' )(a1 )
383
+
384
+ output_layers .append (layers .Dense (num_classes [i ], name = 'age' , activation = 'softmax' )(a2 ))
348
385
elif label [i ] == 'race' :
349
- output_layers .append (layers .Dense (num_classes [i ], name = 'race' )(last_hidden ))
386
+ r1 = layers .Dense (4096 , activation = 'relu' )(flatten )
387
+ r2 = layers .Dense (2048 , activation = 'relu' )(r1 )
388
+ output_layers .append (layers .Dense (num_classes [i ], name = 'race' , activation = 'softmax' )(r2 ))
350
389
351
390
352
391
model = keras .Model (inputs = image_input , outputs = output_layers )
353
392
393
+ print (model .summary ())
394
+
354
395
keras .utils .plot_model (model , "task4.png" , show_shapes = True )
355
396
356
397
# Using adam for all tasks
357
398
model .compile (
358
- optimizer = tf .keras .optimizers .SGD (learning_rate = 0.1 ),
359
- loss = l
399
+ optimizer = tf .keras .optimizers .SGD (learning_rate = 0.01 ),#, decay=0.1/eps),
400
+ loss = l ,
401
+ metrics = ["accuracy" ],
402
+ #loss_weights = l_wts
360
403
)
361
404
362
405
# Fit the model
@@ -367,19 +410,38 @@ def task4(label = ['gender', 'age']):
367
410
batch_size = 128
368
411
)
369
412
370
- # Plot
371
- plt .plot (history .history ['accuracy' ], label = 'Training' )
372
- plt .plot (history .history ['val_accuracy' ], label = 'Validation' )
373
- plt .title ('Task {} Training and Validation Accuracy' .format (4 ))
374
- plt .xlabel ('Epoch' )
375
- plt .ylabel ('Accuracy' )
376
- plt .legend ()
413
+ (fig , ax ) = plt .subplots (len (label ), 1 , figsize = (8 , 8 ))
414
+ fig .subplots_adjust (hspace = 0.5 )
415
+ for (i , l ) in enumerate (label ):
416
+ # plot the loss for both the training and validation data
417
+ ax [i ].set_title ("Accuracy for {}" .format (l ))
418
+ ax [i ].set_xlabel ("Epoch #" )
419
+ ax [i ].set_ylabel ("Accuracy" )
420
+ ax [i ].plot (np .arange (0 , eps ), history .history [l + '_accuracy' ], label = 'Training' )
421
+ ax [i ].plot (np .arange (0 , eps ), history .history ["val_" + l + '_accuracy' ],
422
+ label = 'Validation' )
423
+ ax [i ].legend ()
377
424
plt .show ()
378
425
426
+ preds = model .predict (Xval )
379
427
for i in range (len (label )):
380
- plot_cm (model , Xval , Yval [i ], val_map [i ], title = 'Task {}, Label = {} Validation Confusion Matrix' .format (4 , label [i ]))
428
+
429
+ num_classes = len (set (Yval [i ]))
430
+
431
+ # Sigmoid decision rule:
432
+ if num_classes == 2 :
433
+ ypred = [1 if p > 0.5 else 0 for p in preds [i ]]
434
+ else :
435
+ ypred = [np .argmax (p ) for p in preds [i ]]
436
+
437
+ cm = confusion_matrix (Yval [i ], ypred )
438
+ df_cm = pd .DataFrame (cm / np .sum (cm ), index = [val_map [i ][j ] for j in range (len (set (Yval [i ])))],
439
+ columns = [val_map [i ][j ] for j in range (len (set (Yval [i ])))])
440
+
441
+ plt .figure (figsize = (10 , 7 ))
442
+ sns .heatmap (df_cm , annot = True , fmt = '.2%' )
443
+ plt .title ('Task {}, {} Validation Confusion Matrix' .format (4 , label [i ]))
444
+ plt .show ()
381
445
382
446
if __name__ == '__main__' :
383
- evoke_task ('task2' , 'age' )
384
- #a,b,c,d = load_data()
385
- #to_numeric(d['gender'])
447
+ task4 ()
0 commit comments