In [1]:
import pandas as pd
import numpy as np
import tensorflow as tf
In [2]:
# read in some of the data
df = pd.read_csv('../data/facial keypoints training.csv', nrows=5000)
In [3]:
# check that the image is really 96*96
print(len(np.fromstring(df.Image.iloc[0], dtype=int, sep=' ')))
print('{}, {}'.format(96**2, df.columns.tolist()))
In [4]:
df = df[['left_eye_center_x', 'left_eye_center_y','Image']]
# for now only train on the left eye center
df = df[df['left_eye_center_x'].notnull() & df['left_eye_center_y'].notnull()]
In [5]:
# check how much data is left of the initial blob
print(df.shape)
In [6]:
# round the left eye x, y coordinates to integers (could multiply by powers of ten to get higher position resolution)
df[['left_eye_center_x', 'left_eye_center_y']] = df[['left_eye_center_x', 'left_eye_center_y']].round(0)
print(df[['left_eye_center_x', 'left_eye_center_y']].head())
In [7]:
# encode. must give column names if numeric
left_eye_x = pd.get_dummies(df['left_eye_center_x'], columns=['left_eye_center_x'])
left_eye_y = pd.get_dummies(df['left_eye_center_y'], columns=['left_eye_center_y'])
In [8]:
# convert faces to dataframe
faces = df.Image.apply(lambda x: pd.Series(np.fromstring(x, dtype=np.float32, sep=' ')))
In [9]:
# see the results
print(faces.head())
print(faces.shape)
In [10]:
# free space
del df['Image']
faces = faces.as_matrix()
left_eye_x = left_eye_x.as_matrix()
print(faces.shape)
print(left_eye_x.shape)
In [11]:
# tf doesn't appear to like cross-type operations. keep everything float32
print(type(faces[0,0]))
In [13]:
num_labels = left_eye_x.shape[1]
image_size = 96
graph = tf.Graph()
with graph.as_default():
# graph
face = tf.placeholder(tf.float32, [None, image_size**2])
label = tf.placeholder(tf.float32, [None, 48])
weights = tf.Variable(tf.truncated_normal([image_size*image_size, num_labels]))
biases = tf.Variable(tf.zeros([num_labels]))
#print('{},{}'.format(type(train_dataset), type(weights)))
# loss
logits = tf.matmul(face, weights) + biases
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=label, logits=logits))
# add to export graph collection
tf.add_to_collection('logits', logits)
# optimizer
optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
# predictions
train_prediction = tf.nn.softmax(logits)
In [17]:
num_steps = 1000
with tf.Session(graph=graph) as session:
# initialise graph
tf.global_variables_initializer().run()
# saver
saver = tf.train.Saver()
# define what you mean by accuracy (to-do: add another measure)
def accuracy(predictions, labels):
return (100.0 * np.sum(np.argmax(predictions, 1) == np.argmax(labels, 1)) / predictions.shape[0])
# optimise the coefficients of the graph using the loss function and optimiser
for step in range(num_steps):
_, l, predictions = session.run([optimizer, loss, train_prediction], feed_dict={face:faces, label:left_eye_x})
if (step % 50 == 0):
print('Loss at step {}: {}'.format(step, l))
print('Training accuracy: %.1f%%' % accuracy(predictions, left_eye_x))
try:
saver.save(session,'../models/left-eye-test-model')
saver.export_meta_graph('../models/left-eye-test-model' + '.meta')
print('saved model to left-eye-test-model.meta')
except Exception as e:
print(repr(e))
In [ ]: