Skip to content

Commit 8bc223f

Browse files
committed
adding updated code
1 parent dc20f84 commit 8bc223f

File tree

2 files changed

+116
-51
lines changed

2 files changed

+116
-51
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fairface_*.csv
2+
train/*
3+
val/*

Project3/project3.py

+113-51
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def plot_cm(model, Xval, Yval, val_map, title):
124124
df_cm = pd.DataFrame(cm/np.sum(cm), index = [val_map[i] for i in range(len(set(Yval)))],
125125
columns = [val_map[i] for i in range(len(set(Yval)))])
126126

127-
#plt.figure(fig_size = (10, 7))
127+
plt.figure(figsize = (10, 7))
128128
sns.heatmap(df_cm, annot=True, fmt = '.2%')
129129
plt.title(title)
130130
plt.show()
@@ -173,6 +173,10 @@ def train_model(model, args, label = 'gender'):
173173
loss = args['loss'], metrics = ['accuracy']
174174
)
175175

176+
print(model.summary())
177+
178+
keras.utils.plot_model(model, str(args['task_number'])+'_'+label+'.png', show_shapes=True)
179+
176180
# Fit the model
177181
history = model.fit(
178182
Xtrain, Ytrain,
@@ -190,31 +194,28 @@ def train_model(model, args, label = 'gender'):
190194
plt.legend()
191195
plt.show()
192196

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))
194198

195199
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
198201
- Parsing done in if main statement
199-
200-
Arguments:
201-
----------
202202
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+
"""
206207

207208
if task_number == 'task1':
208209

209210
if label == 'gender':
210211
l = 'binary_crossentropy'
211-
eps = 13
212+
eps = 50
212213
elif label == 'age':
213214
l = tf.keras.losses.SparseCategoricalCrossentropy()
214-
eps = 11
215+
eps = 50
215216
elif label == 'race':
216217
l = tf.keras.losses.SparseCategoricalCrossentropy()
217-
eps = 11
218+
eps = 50
218219

219220
model = tf.keras.Sequential()
220221
model.add(keras.Input(shape=(32,32, 1)))
@@ -260,32 +261,49 @@ def evoke_task(task_number = 'task1', label = 'gender'):
260261

261262
if label == 'gender':
262263
l = 'binary_crossentropy'
263-
eps = 13
264+
eps = 50
265+
lr = 0.01
264266
elif label == 'age':
265267
l = tf.keras.losses.SparseCategoricalCrossentropy()
266-
eps = 11
268+
eps = 50
269+
lr = 0.1
267270
elif label == 'race':
268271
l = tf.keras.losses.SparseCategoricalCrossentropy()
269-
eps = 11
272+
eps = 50
273+
lr = 0.01
270274

271275
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'))
274279
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))
275291
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'))
277295

278296
args = {
279297
'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,
282300
'batch_size': 128,
283301
'task_number': 3
284302
}
285303

286304
train_model(model, args, label)
287305

288-
def task4(label = ['gender', 'age']):
306+
def task4(label=['gender','age']):
289307
'''
290308
Runs task 4
291309
Note: this function does not perform advanced preprocessing other than loading data
@@ -295,14 +313,9 @@ def task4(label = ['gender', 'age']):
295313
296314
Arguments:
297315
----------
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
306319
307320
Returns:
308321
--------
@@ -313,6 +326,7 @@ def task4(label = ['gender', 'age']):
313326
Xtrain, train_labels, Xval, val_labels = load_data()
314327

315328
l = []
329+
l_wts = []
316330
Ytrain = []
317331
Yval = []
318332
num_classes = []
@@ -326,37 +340,66 @@ def task4(label = ['gender', 'age']):
326340
Yval.append(val_dat)
327341
if i == 'gender':
328342
l.append('binary_crossentropy')
343+
l_wts.append(0.1)
329344
elif i == 'age':
330345
l.append(tf.keras.losses.SparseCategoricalCrossentropy())
346+
l_wts.append(4.0)
331347
elif i == 'race':
332348
l.append(tf.keras.losses.SparseCategoricalCrossentropy())
349+
l_wts.append(1.0)
333350

334-
eps = 30
351+
eps = 50
335352

336353
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)
341372

342373
output_layers = []
343374
for i in range(len(label)):
344375
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))
346380
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))
348385
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))
350389

351390

352391
model = keras.Model(inputs=image_input, outputs=output_layers)
353392

393+
print(model.summary())
394+
354395
keras.utils.plot_model(model, "task4.png", show_shapes=True)
355396

356397
# Using adam for all tasks
357398
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
360403
)
361404

362405
# Fit the model
@@ -367,19 +410,38 @@ def task4(label = ['gender', 'age']):
367410
batch_size = 128
368411
)
369412

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()
377424
plt.show()
378425

426+
preds = model.predict(Xval)
379427
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()
381445

382446
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

Comments
 (0)