【caffe】基于caffe的分类模型训练及人脸识别应用
0、概述
主要介绍用caffe训练分类模型的方法,你要做的事情有:
1)配置好caffe
2)https://blog.****.net/gaohuazhao/article/details/69568267
跟着做一遍你就能上手用caffe训练模型了,上面这个博客还提供了完整文件,非常友好
https://github.com/EddyGao/Caffe-taobao_Image-Identification
3)这篇文章和2)不同的两个地方,一是我用自己的方式总结一下要用到哪些文件,每个文件的作用是什么,二是介绍如何基于现有的模型去做finetune
大家可以下载下面:
https://pan.baidu.com/s/18sYAHzU7EouFzgwbaQe0Hg
是在2)的基础上加了用squeezenet模型做finetune的部分。
使用方法是:
1.将finetune.sh和train.sh放入caffe根目录下
2.将myfile4解压后放入caffe的examples目录下
3.在caffe根目录下打开shell,输入
sh train.sh(即采用博文中的方法进行训练)
sh finetune.sh(即用finetune squeezenet训练,效果并不好,只是做个例子)
当然这里面是有坑的,跑train.sh应该没有问题,跑finetune.sh会有错,因为里面相关文件的路径我写的是绝对路径,和你自己的电脑肯定不一样。为的就是让你自己懂得如何去改那些关键路径,使它可以运行。
1、讲解各个文件的作用(配合文件myfile4去看)
(文件名其实无所谓,只要每个文件中指定其他文件的路径对的上就可以)
1)train.txt和val.txt
【用于指定图片所在位置与对应类别】
train.txt中是所有训练图片所在位置及其对应的标签。
val.txt中是所有测试图片所在位置及其对应的标签。
一般通过写sh或py脚本来生成这两个文件,此例中就是用create_filelist.sh实现的
2)create_lmdb.sh
【用于生成lmdb数据文件】
lmdb是caffe可读取的一种数据形式,生成lmdb数据文件就包括了之前的所有图片及标签信息了(你把原先的图片删了也没事)
3)create_meanfile.sh
【用于生成均值文件】
均值文件的意义就是保存所有训练图片R\G\B三个通道分别的均值。如果不生成这个文件,在后面.prototxt自行设定均值也是可以的。
4) xxx_train_val.prototxt
【用于指定训练的输入文件及训练模型】
4.1 在文件中指定输入文件、均值文件
xxx_train_val.prototxt只是常见的命名形式,你要命名成其他也可以,只要在下面介绍的文件5)中指定对应的文件就没问题,当然后缀必须是.prototxt。这里注意几个东西
输入层这边,data_param的source这一行就是输入第二步中生成的lmdb文件的路径。那么在squeezenet_v1.1_train_val.prototxt文件中,相应的路径我写的是绝对路径,这里是你们要根据自己电脑的情况改的(改成相对或者符合你电脑安装情况的绝对路径)(其他要改的地方自行寻找)
mean_file就是指定3)中生成的均值文件路径。如果没有生成均值文件,你可以人为指定均值,像下面这张图上的这种写法。另外介绍一下,crop_size表示输入图片裁剪到多大,我这边是注释掉了。
4.2 更改模型
拿其中这一层为例,你可以修改层的类型(type),层的名字(name),层的连接关系(top,bottom),具体的层参数,这层是卷积,所以是卷积参数(num output:输出的feature map个数,对于卷积而言就是卷积核个数 pad:边缘填充尺寸 kernel_size:卷积核尺寸 weight_filter:权值初始化方式)
更加详细的参数介绍可以移步 https://blog.****.net/s151506879/article/details/52138516
4.3 Finetune的话我要在这个文件里改什么?
finetune一般是通过下载一个别人已经训练好的模型(有caffemodel和描述模型的这个prototxt文件),那么我们首先要说下对于这个prototxt文件改什么。
修改一、按照自己的实际情况生成数据,然后在这个文件里指定清楚数据文件、均值文件的位置,视情况是否裁剪、旋转输入图片等。就是前面介绍的工作。
修改二、根据分类的类别数来更改文件中最后一处输出维度(num_ouput),并修改相应层的名字。
例如对squeezenet的修改,因为上述淘宝案例是一个10分类问题,那么在conv10这里我就把这层的num_output改成10,同时这层原本叫conv10,我现在改名为conv10_new。这是因为finetune的时候会读取对应的caffemodel文件,你改了结构,但对应的权值还是有1000个,就会不匹配。如果把层的名字改了,那么caffe读不到对应层的权重时,就会把这层重新初始化。
当然你把conv10名字改了之后,还要把和conv10所有有连接关系的层中,top或bottom关键字出现conv10给对应改掉。比如
5)xxxx_solver.protxt
这个文件的内容长这个样子。里面全部都是用来设置训练参数的。
其中,net就是文件4)的路径。
具体每个参数的作用直接参考 https://blog.****.net/sxs11/article/details/53690038
6)train.sh 和 finetune.sh
就是linux的sh脚本,其实和你直接在shell里面输入对应内容是一个作用。你也可以在caffe根目录下打开shell(当前路径必须是caffe根目录)
输入
build/tools/caffe train -solver examples/myfile4/myfile4_solver.prototxt -weight examples/myfile4/my_iter_2000.caffemodel
等同于输入sh train.sh
输入
build/tools/caffe train -solver examples/myfile4/squeezenet_v1.1_solver.prototxt -weights examples/myfile4/squeezenet_v1.1.caffemodel
等同于输入sh finetune.sh
2、总结一下caffe训练流程(倒叙)
要用caffe训练模型,最后都是在shell输入形如 build/tools/caffe train -solver xxx_solver.prototxt -weights xx.caffemodel
-weight xx.caffemodel是训练开始时载入的网络的各种参数,你如果不写,重新开始训练也可以。
-xx_solver.prototxt内第一行指定了网络结构文件(另一个prototxt文件,一般命名为xx_train_val.prototxt或者xx_train_test.prototxt)的位置,之后指定了训练参数。
网络结构文件中不仅指定了网络结构,也指定了输入数据文件和均值数据文件的位置,并且你如果要finetune记得在这个文件里改输出种类数和层的名字。(见4.3)。输入数据文件和均值文件是需要你自己生成的,生成方式见第一部分的1)2)3)。
3、如何使用生成的模型做分类?
一般你下载的现成模型文件里会有一个deploy.prototxt,这个文件和xx_train_val.prototxt非常相似,但是它不用指定输入数据地址,也没有反向传播训练的过程。把这个文件做和xx_train_val.prototxt对应的修改(改输出数,层的名字等)。改好后一般用C++或者python的caffe接口来具体使用。
squeezenet的caffe模型
https://github.com/Kuldeep-Attri/Caffe-SqueezeNet
PYTHON参考
https://blog.****.net/baterforyou/article/details/71430284
C++参考
https://blog.****.net/jiongnima/article/details/70197866
4、如何用上述方法做人脸识别?
我们的做法可能比较简单,会有其他更好的做法,仅提供一种思路。
下载一个已经训练好的模型,如追求速度我们就可以用squeezenet,精度可以用VGG等。
收集并分类人脸图片,例如1W个人,每个人有一到多张图,做好标签文件,生成数据和均值文件。
用caffe去finetune我们下载的模型,因为是1W个人,所以训练一个1W分类问题的模型,除了改变类别数外,也可以自己改动网络结构。
实际运行时只取最终输出之前的某个conv层或者relu层或者pooling层输出(视效果而定取哪一层),这里取出来就是一个特征向量了。那么输入A和输入B时得到的是两个不同的特征向量,用各种方式去比较特征向量,可以通过判定向量近似程度进而判定两张图片是不是同一个人。