论文FaceNet: A Unified Embedding for Face Recognition and Clustering
代码:https://github.com/davidsandberg/facenet
需要注意的地方:
源码中的facenet里面最后输出直接是全连接输出,但是论文中却说使用的是模为1的输出,因此train_tripletloss.py文件中在网络预测以后,又对预测的logits后面加上了:
tf.nn.l2_normalize(x, dim, epsilon=1e-12, name=None)
上式:
x为输入的向量;
dim为l2范化的维数,dim取值为0或0或1;
epsilon的范化的最小值边界;
然后再进行训练。因此训练中存储的模型结构最后的输出也加上了这个操作,因此在预测时结果直接就是被归一化的。
大体思路
训练一个将人脸抽象成128维向量的神经网络,不是一个人脸那么欧氏距离就大,否则就小。
流程
准备好人脸图片,调整为220大小,白化操作。
源码中,网络正确预测tf.subtract(pos_dist, neg_dist)是小于0,因此让loss等于0。
网络错误预测tf.subtract(pos_dist, neg_dist)是大于0,因此最小化这个值,这个值当然是越小越好。
增加了一个偏移量alpha,这个值找了半天没找到,应该是大于0的但也不能太大的一个数。
pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), 1) neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), 1) basic_loss = tf.add(tf.subtract(pos_dist, neg_dist), alpha) loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0)
然后就可以正常训练了,就是从训练数据中随机抽出来三个这种组合,然后直接就可以训练了。