本篇文章主要记录的是人脸检测数据源制作与ALEXNET网络训练实现检测到人脸(基于caffe)。
1、数据获取
数据获取:
① benchmark是一个行业的基准(数据库、论文、源码、结果)
② 优秀论文,通常实验阶段都会介绍它所使用的数据集,公开数据集可以下载。申请数据集的时候,最后使用学校的数据集。
③ 论坛或者交流社区:如thinkpace
④ 数据规模,越大越好 如本实验中4w多
二分类数据:第一类人脸,第二类非人脸
人脸数据:路径/xxx.jpg 坐标
非人脸数据:只要不是人脸都可以
对于正样本:裁剪的操作,根据标注的坐标把人脸裁剪出来。可以用opencv这个工具来完成制作人脸数据。要检测一下,看看数据源有没有问题。
对于负样本:进行一个随机裁剪,IOT这个比例(重叠的比例)在原始的数据当中,IOU<0.3认为是一个负样本是,最好是拿没有人脸数据的当作负样本(根据实际情况来选择)。
①制作LMDB数据源(用于单label值)(其实就是caffe支持的非常常用的分类数据源)
②写两个txt文件, caffe的分类值是从0开始的
Train.txt
0/xxx.jpg 0(表示在0目录下某张图片的名称, 且label值(分类值)为0)
1/xxx.jpg 1(表示在1目录下某张图片的名称, 且label值(分类值)为1)
Val.txt(类别0和1没有进行目录分类)
xxx.jpg 0
xxx jpg 1
③制作LMDB数据源,用caffe提供的脚本文件 脚本文件前几行改成自己的目录,sh LMDB脚本文件 生成LMDB数据源,文件很大。
脚本如下所示:
1 #!/usr/bin/env sh 2 # Create the face_48 lmdb inputs 3 # N.B. set the path to the face_48 train + val data dirs 4 5 EXAMPLE=/home/×××/face_detect 6 DATA=/home/×××/face_detect 7 TOOLS=/home/×××/caffe/build/tools 8 9 TRAIN_DATA_ROOT=/home/×××/face_detect/train/ 10 VAL_DATA_ROOT=/home/×××/face_detect/val/ 11 12 # Set RESIZE=true to resize the images to 60 x 60. Leave as false if images have 13 # already been resized using another tool. 14 RESIZE=true 15 if $RESIZE; then 16 RESIZE_HEIGHT=227 17 RESIZE_WIDTH=227 18 else 19 RESIZE_HEIGHT=0 20 RESIZE_WIDTH=0 21 fi 22 23 if [ ! -d "$TRAIN_DATA_ROOT" ]; then 24 echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT" 25 echo "Set the TRAIN_DATA_ROOT variable in create_face_48.sh to the path" 26 "where the face_48 training data is stored." 27 exit 1 28 fi 29 30 if [ ! -d "$VAL_DATA_ROOT" ]; then 31 echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT" 32 echo "Set the VAL_DATA_ROOT variable in create_face_48.sh to the path" 33 "where the face_48 validation data is stored." 34 exit 1 35 fi 36 37 echo "Creating train lmdb..." 38 39 GLOG_logtostderr=1 $TOOLS/convert_imageset 40 --resize_height=$RESIZE_HEIGHT 41 --resize_width=$RESIZE_WIDTH 42 --shuffle 43 $TRAIN_DATA_ROOT 44 $DATA/train.txt 45 $EXAMPLE/face_train_lmdb 46 47 echo "Creating val lmdb..." 48 49 GLOG_logtostderr=1 $TOOLS/convert_imageset 50 --resize_height=$RESIZE_HEIGHT 51 --resize_width=$RESIZE_WIDTH 52 --shuffle 53 $VAL_DATA_ROOT 54 $DATA/val.txt 55 $EXAMPLE/face_val_lmdb 56 57 echo "Done." 58 Status API Training Shop Blog About
2、训练ALEXNET网络
2.1、实现步骤
依据ALEXNET网络结构来编写train.prototxt,指定对应参数(例如下面代码),训练时所找的网络,顺便介绍一些其他注意事项:
(1)batch_size为每次训练的样本数目 一般为64或更大等
(2)均值操作 mean_file,作者说影响不大
(3)mirro:true 即开启镜像操作,相当于图像对此泛转,训练集翻倍
layer { name: "data" type: "Data" top: "data" top: "label" include { # 规定只在测试的时候使用该层 phase: TEST } transform_param { # 测试的时候就不做镜像了 mirror: false crop_size: 227 mean_file: "data/ilsvrc12/imagenet_mean.binaryproto" } data_param { source: "examples/imagenet/ilsvrc12_val_lmdb" batch_size: 50 backend: LMDB } }
图1 ALEXNET网络结构
下一步需要修改solver.prototxt,test_iter:一次测试中,要测试的多少个batch最好让test_iter*batch_size=整个测试样本数目(依据电脑性能)base_Ir基础学习率,非常重要,学习率不能太大,太大模型不能收敛到合适的地方,一般为0.001 display = 1000左右 ,运行train.sh ,生成训练的模型.caffemodel。
人脸代码实现:
多尺度的人脸检测
(1) caffemodel转换成全卷积格式
(2) 经过多个scale,即图像金字塔
(3) 前向传播,得到特征图,概率值矩阵
(4) 反变换,映射到原图上的坐标值
(5) NMS非极大值抑制
2.2、思考
网络训练的速度与什么相关?(抛开硬件)
(1)网络的模型大小(ALEXNET-8层 VGG-16层),网络越大速度越慢;
(2)数据输入的大小,227*227 和 32*32的,可能慢几百倍-(影响最大)。输入越大,网络越慢
概念介绍及NMS说明
(1)滑动窗口概念
(2)scale变换
(3)全连接层->全卷积层(输入可以为大小不同的图像)
(4)对于检测人脸的多个框如何解决->思路为非极大值抑制算法NMS
2.3、问题
(1)速度慢,因为做了多个scale,每个scale都要进行一次前向传播
(2)准确率的问题,采用VGG网络-16层卷积,相比AlexNet网络准确率更高
(3)数据增强策略,在原始的数据上进行平移、旋转等
解决方案:
(1)采取级联的网络,再加上矫正网络,来源于论文(CVPR2015_CasCN..)