【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。这里注意几个东西

    【caffe】基于caffe的分类模型训练及人脸识别应用

    输入层这边,data_param的source这一行就是输入第二步中生成的lmdb文件的路径。那么在squeezenet_v1.1_train_val.prototxt文件中,相应的路径我写的是绝对路径,这里是你们要根据自己电脑的情况改的(改成相对或者符合你电脑安装情况的绝对路径)(其他要改的地方自行寻找)

    mean_file就是指定3)中生成的均值文件路径。如果没有生成均值文件,你可以人为指定均值,像下面这张图上的这种写法。另外介绍一下,crop_size表示输入图片裁剪到多大,我这边是注释掉了。

【caffe】基于caffe的分类模型训练及人脸识别应用

    4.2 更改模型

    【caffe】基于caffe的分类模型训练及人脸识别应用

    拿其中这一层为例,你可以修改层的类型(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),并修改相应层的名字。

【caffe】基于caffe的分类模型训练及人脸识别应用

    例如对squeezenet的修改,因为上述淘宝案例是一个10分类问题,那么在conv10这里我就把这层的num_output改成10,同时这层原本叫conv10,我现在改名为conv10_new。这是因为finetune的时候会读取对应的caffemodel文件,你改了结构,但对应的权值还是有1000个,就会不匹配。如果把层的名字改了,那么caffe读不到对应层的权重时,就会把这层重新初始化。

     当然你把conv10名字改了之后,还要把和conv10所有有连接关系的层中,top或bottom关键字出现conv10给对应改掉。比如

【caffe】基于caffe的分类模型训练及人脸识别应用

5)xxxx_solver.protxt

    这个文件的内容长这个样子。里面全部都是用来设置训练参数的。

    其中,net就是文件4)的路径。

    具体每个参数的作用直接参考 https://blog.****.net/sxs11/article/details/53690038

    【caffe】基于caffe的分类模型训练及人脸识别应用

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时得到的是两个不同的特征向量,用各种方式去比较特征向量,可以通过判定向量近似程度进而判定两张图片是不是同一个人。