在所有的数据都处理完了之后,接下来就可以进行模型的训练了。

在Github上FaceNet项目的介绍中有softmax和论文中提到的三元损失训练triplet两种方式,这边简单的介绍下softmax的训练方法。

FaceNet已经将所有的方法都已经封装好,训练程序在src目录下的train_softmax.py文件中,在训练之前,我们首先要简单的修改下这份文件,让它适用于当前版本。

  1. 找到260行,搜索iteritems也可以
for key, value in stat.iteritems():

 将iteritems修改为items,在python3中,dict已经没有iteritems方法了

  1. 找到308行,将
if lr<=0:

修改为

if lr is None or lr <= 0:

亲测在最后一轮训练的时候,学习率本来应该是变成-1,然后结束,但是出现了lr变成None的情况

  1. 这一点仅供GPU玩家修改,使用CPU的话就不用修改了,跳过这一点直接训练就好了,找到191行,将
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))

替换成

config = tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False, allow_soft_placement=True)
    config.gpu_options.allow_growth = True
    sess = tf.Session(config=config)

模型训练 

这里在CPU:i7-6700H,显卡:GTX965M,CUDA:9.0,cuDNN:7.0.5的辣鸡笔记本中,采用WebFace数据集进行训练测试

输入运行参数

python src/train_softmax.py --logs_base_dir logs/facenet/ --models_base_dir models/facenet/ --data_dir datasets/CASIA-WebFace_train_182/ --image_size 160 --model_def models.inception_resnet_v1 --lfw_dir datasets/lfw_160/ --optimizer ADAM --learning_rate -1 --max_nrof_epochs 150 --keep_probability 0.8 --random_crop --random_flip --use_fixed_image_standardization --learning_rate_schedule_file data/learning_rate_schedule_classifier_casia.txt --weight_decay 5e-4 --embedding_size 512 --lfw_distance_metric 1 --lfw_use_flipped_images --lfw_subtract_mean --validation_set_split_ratio 0.05 --validate_every_n_epochs 5 --prelogits_norm_loss_factor 5e-4

简单说下上述的参数,当然还有非常多其它未加入的,需要的可以自己去研究源码

非常的直观,其中

--logs_base_dir:是存放训练过程的目录

--models_base_dir:是存放训练结果模型的目录

--data_dir:是训练数据集的目录,可以根据需要自己更改

--model_def:是训练的神经网络方法,这里采用resnet

--lfw_dir:存放lfw数据集的位置,作用是在训练过程中对模型进行测试,可以不加,但是推荐!!!

--learning_rate:学习率的设置,学习率在训练过程中是非常重要的,设置的太大模型难以收敛,设置的太小模型容易过拟合,所有在训练过程中基本上会选择动态学习率的设置,就是下面要讲到的参数

--learning_rate_schedule_file:学习率时间计划表,我们来打开其中一个文件进行分析

tensorflow 分类模型评估 tensorflow 模型训练_Python

这个是vggface2的训练示例,在epoch0-99轮的时候学习率设置为0.05,100-199轮设置为0.005,200到275轮设置为0.0005,通过这个方法决定模型训练的轮数和相应的学习率变化,可以手动进行修改自定义

在讲完了参数之后,我们开始进行训练,使用GPU进行训练的童鞋有可能遇到一个问题,如下

tensorflow 分类模型评估 tensorflow 模型训练_TensorFlow_02

如果是类似的错误的话,恭喜你,你的显卡和我的一样辣鸡...

FaceNet项目默认一次喂入计算图90张照片,如果显卡的显存不够的话,就会报出OOM的错误,这个时候只需要减少一次的喂入量就行了,添加参数

--batch_size 50

tensorflow 分类模型评估 tensorflow 模型训练_tensorflow 分类模型评估_03

训练一步0.8s,还算可以接受的时间,虽然我觉得喂入数量太少对模型并不是一个很好的选择,但是在CPU下亲测训练一步需要30s+,为了狗命着想,只能忍忍了

接着就是最关键的一点,动态显示训练过程

既然我们放入lfw数据集,那当然需要最大限度利用起来才行,打开一个新的终端,输入命令,定位到logs目录下

tensorboard --logdir=logs/facenet --port 6006

tensorflow 分类模型评估 tensorflow 模型训练_tensorflow 分类模型评估_04

打开网页 

tensorflow 分类模型评估 tensorflow 模型训练_TensorFlow_05

楼主训练了30个小时,最后模型正确率在98.8%左右,很可惜没有达到99%,也许加大batch的数量和增加训练轮数就可以了,不过就结果来说还是很不错的,毕竟训练成功了

同样,如果想要尝试大量数据的训练,完全okk,因为项目会自动保存最新的模型,假使一不小心训练中断了,同样可以加载之前训练的结果继续训练,在源码的参数中有说明