其实半年多前就已经把insightface训练等一系列环节弄熟了,不得不说IBUG组的这个模型确实是开源界的翘楚,但是还是存在一些问题在某些程度上和商汤云从等大厂存在一点差距,这不妨碍大部分人日常人脸识别的使用。给大佬点烟
xxx.bin的制作这次也不更新截图了,等下次要用的时候一起截图更新吧~
前言
公司希望使用新的人脸识别算法去升级老的算法,于是有了此次爬坑之旅
使用的是Mxnet的版本,直接从git上lclone一份代码,目前我拉下来的代码里是有问题的,我会在后续里写出。
ps,第一次使用MXNET,如果有说的不对的地方请指出谢谢~
安装准备
按照git地址上先将Mxnet安装成功,地址如下
https://github.com/deepinsight/insightface
因为要求使用的是python2.x,我这边直接在py27这个环境下配置的程序,大家也可以单独新建一个环境,都ok~然后按照要求安装好各种包。
更新
当初使用的是src文件下的train.py,这个训练脚本应该是支持py27的。后续再recognition文件下的train.py是是支持py36的,后续的训练其实可以使用这个脚本,并且这个脚本可以显示loss。建议使用这个,使用方式非常像。
很久没训练这个模型了,就不截图,如果能src下的跑通另外的训练脚本应该问题不大。
哪天闲了考虑更新。
本地数据准备
Mxnet要求的数据格式是与tensoflow不同的,这里需要的是:
/
train.lst
train.idx
train.rec
property
lfw.bin
cfp_fp.bin
agedb_30.bin
xxx.bin
1
2
3
4
5
6
7
8
9
其中train.idx 和 train.rec分别是数据偏移索引和数据本身的文件. property代表数据集属性
.idx和.rec可以理解为TF里的Tf.record,是mxnet的数据形势,proprty是一个文件,里面记录里有多少个种类,图像的shape的信息。剩下的。bin文件是在Validation部分用的,就是验证集的部分。
更新这里的xxx.bin当时不太会生成,其实这个就是用自己数据做成的验证集。.idx和.rec是本地数据的训练集。
直接运行时会遇到 AttributeError: module ‘facenet’ has no attribute ‘store_revision_info’, AttributeError: module ‘facenet’ has no attribute ‘get_dataset’,的错误, 这是导入时的错误,部分版本应该会遇到。
直接修改导入
使用下载facenet的工程,使用代替
import facenet.src.facenet as facenet
1
将文件复制到上一级目录下使用,因为align.face_detect和矫正代码在同一目录下。
insightface的代码face2rec2.py代码有些问题,猜测时作者更新以后忘记里。
使用Github的incubator-mxnet工程里的im2rec.py脚本。
生成.lst文件,最新的mxnet代码里,直接使用–list和–recursive,不用添加ture。地址最好选择绝对地址,不用相对地址
生成rec和idx文件时,使用同一个.py。–num-thread为多线程操作
生成的.lst .rec .idx 都在Mxtest目录下
python im2rec.py --list --recursive /opt/app/OCR/face-for-train/Mxtest/train /opt/app/OCR/face-for-test/lfw_mxnet/
python im2rec.py --num-thread 4 /opt/app/OCR/face-for-train/Mxtest/train /opt/app/OCR/face-for-test/lfw_mxnet/
1
2
之后会生成
开始训练
CUDA_VISIBLE_DEVICES='0,1' python -u train.py --network r100 --data-dir ../datasets/faces_glintasia/ --ckpt 2 --target lfw --version-se 0 --per-batch-size 64
1
CUDA_VISIBLE_DEVICES='0,1' python -u train.py --network r100 --data-dir ../datasets/faces_glintasia/ --ckpt 2 --target lfw --version-se 0 --per-batch-size 64 --pretrained ../models/model-r100-ii/model,0 --lr 0.001 --prefix ../model_v2/model-r100-v2
1
作者在issus里说,他移除里fc7点全部权重,所以我们在新的数据集上训练的acc会从0开始上升,可以看到上升的很快,远比我们从0开始训练的快的多。
参考何凯明大神去年关于pre-trained model的论文,在预训练模型上进行训练会加快训练速度,但最终的结果的精度并不会有本质上的提高。这里如果可以在网络结构里加入GroupN,应该会有1%到2%mAP的提升,当然不知道人脸识别里这个参数会是多少
这里的准确度就是在lfw上跑的准确度,因为我们是在其基础上进行finetuning的,所以在lfw上的acc已经达到99.8%
[lfw][4000]XNorm: 23.678398
[lfw][4000]Accuracy-Flip: 0.99817+-0.00229
1
2
在训练了10个epoch后,网络基本收敛,在glint-asia上的acc达到92%左右
05-13 07:05 root INFO Epoch[8] Train-acc=0.922817
05-13 07:05 root INFO Epoch[8] Train-lossvalue=0.503714
1
2
出现这种问题,cudaMalloc failed: out of memory
Traceback (most recent call last):
File "train.py", line 1025, in <module>
main()
File "train.py", line 1022, in main
train_net(args)
File "train.py", line 1016, in train_net
epoch_end_callback = epoch_cb )
File "/opt/app/anaconda3/envs/py27/lib/python2.7/site-packages/mxnet/module/base_module.py", line 529, in fit
self.update()
File "/opt/app/anaconda3/envs/py27/lib/python2.7/site-packages/mxnet/module/module.py", line 664, in update
self._kvstore, self._exec_group.param_names)
File "/opt/app/anaconda3/envs/py27/lib/python2.7/site-packages/mxnet/model.py", line 153, in _update_params_on_kvstore
kvstore.push(name, grad_list, priority=-index)
File "/opt/app/anaconda3/envs/py27/lib/python2.7/site-packages/mxnet/kvstore.py", line 234, in push
self.handle, mx_uint(len(ckeys)), ckeys, cvals, ctypes.c_int(priority)))
File "/opt/app/anaconda3/envs/py27/lib/python2.7/site-packages/mxnet/base.py", line 252, in check_call
raise MXNetError(py_str(_LIB.MXGetLastError()))
mxnet.base.MXNetError: [11:07:49] src/storage/./pooled_storage_manager.h:143: cudaMalloc failed: out of memory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
实际上就是爆显存了,降低batchsize到64就好了
制作本地数据的验证集xxx.bin
打包 lfw2pack.py
需要制作pairs.txt
pairs.txt第一行需要写清有多少个set的数据,和每个set多少个正样本
详情看下面这个readme
http://vis-www.cs.umass.edu/lfw/README.txt
parser.add_argument('--data-dir', default='', help='')
parser.add_argument('--image-size', type=str, default='112,96', help='')
parser.add_argument('--output', default='', help='path to save.')