关于fine-tuning的几个小问题:
1、fine-tuning是什么意思
答:所谓fine-tuning就是微调的意思,也就是在一个已经有了不错的performance的网络基础上,针对自己的任务微小的调整网络中的参数。
2、为何要fine-tuning
答:因为我们做的方向经常是一些特定领域的识别分类任务,比如人脸,车辆,植物等等,而像ImageNet这样上千万级的数据库,我们是不会用到其全部的数据,通常我们的数据量都是比较小的。但是对于一个深度神经网络而言,我们需要输入大量的训练图像来训练参数,在这种情况下完全的重新去训练一个网络是非常困难的,所以我们通常会选择在一个比较好的model上来调整参数。
3、目前可以选择用来fine-tuning的原始model有哪些
答:我比较low,知道的不多,自己用过的有:AlexNet,VGG-16,VGG-19,Network In Network等
fine-tuning流程
fine-tuning的步骤与训练神经网络的步骤几乎是一致的,主要有以下几个步骤:
0、下载好已有的模型参数文件
1、准备好训练数据与测试数据
2、计算图像均值
3、修改网络文件
4、修改solver文件中的初始参数
5、开始fine-tuning
接下里针对每一步进行具体的说明
0、下载已有的模型参数文件
已训练好的模型参数文件在caffe中以后缀名为‘.caffemodel’的形式保存,这个文件需要我们自己在网上下载好。
1、准备训练数据与测试数据
这里需要我们将所有的图像生成一个带标签的list,每一行为图像的存储路径和标签,注意标签一定要从0开始,大致的形式如下:
/FMD/image/fabric/fabric_moderate_001_new.jpg 0
/FMD/image/fabric/fabric_moderate_002_new.jpg 0
/FMD/image/fabric/fabric_moderate_003_new.jpg 0
关于如何生成list并将图像顺序打乱可以参考文章:(http://blog.csdn.net/cheese_pop/article/details/52754837)
这样之后,我们将得到两份文本文件一个为训练集,一个为测试集。
2、计算图像均值
在计算图像均值前,我们需要先将训练集转为lmdb的格式,caffe里已经自带了convert_imageset工具,脚本代码如下,如何修改成自己需要的写在了注释里:
#!/usr/bin/env sh
# Create the imagenet lmdb inputs
../caffe-master_github/build/tools/convert_imageset.bin \ #convert_imageset.bin所在路径
/data2 \ #这个行的内容与下一行中涉及到的trian.txt文件中的图片路径拼起来是图像的绝对路径
/temp/train.txt \
./101lmdb LMDB #保存的文件名及格式,(这里保存成LMDB数据格式)
这样生成了lmdb数据后,我们可以开始计算图像均值,代码如下:
../caffe-master_github/build/tools/compute_image_mean.bin 101lmdb mean.binaryproto
其中第一个参数是compute_image_mean.bin工具所在路径,第二个参数就是在上一步生成的lmdb数据库,第三个参数为生成的均值文件。图像的均值文件是以二进制的形式存储的,可以看到里面是类似于乱码的形式。
3、修改网络prototxt文件
1、修改data层的代码,source参数训练集或测试的参数,meanfile参数修改为上一步中生成的mean.prototxt均值文件。
2、修改最后一层的名称和学习率,修改名字是因为预训练模型赋值的时候就会因为名字不匹配从而重新训练,也就达成了我们适应新任务的目的;修改学习率是因为最后一层是重新学习,因此相比较其他层,这一层需要有更快的学习速率,因此我们将weight和bias的学习速率加快10倍。
layer {
bottom: "fc7"
top: "fc8_finetune"
name: "fc8_finetune" #之前是fc8,根据需要,我将其修改为fc8_fintune
type: "InnerProduct"
param{
lr_mult: 100 #weight的学习率要比之前调高10倍
decay_mult: 1
}
param{
lr_mult: 200 #bias的学习率这里要比之前调高10倍
decay_mult: 0
}
inner_product_param {
num_output: 10 #num_output的大小等于数据集的类别数
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 1
}
}
}
layer {
bottom: "fc8_finetune" #注意这里的名字也要改
name: "loss"
type: "SoftmaxWithLoss"
bottom: "label"
include { phase: TRAIN}
}
layer {
name: "accuracy"
type: "Accuracy"
bottom: "fc8_finetune" #注意这里的名字也要改
bottom: "label"
top: "accuracy"
include {phase: TEST}
}
4、修改solver文件中的初始参数
关于solver文件中的各个参数的含义,可以参考文章:caffe中solver.prototxt文件参数解释
与重新训练一个网络不同的是,fine-tuning的时候loss已接近最优值,因此学习率和步长都应该调小一些。需要修改的参数有:
1、test_iter
和test_interval
。这两个只需要根据自己的数据量和网络文件中的batchsize设置的大小进行修改
2、base_lr
调低10倍甚至更多。trick:如果发现在fintune过程中loss的变化比较震荡,可以进一步调低base_lr的大小
3、stepsize
和max_iter
根据情况调低。
5、开始fine-tuning
fine-tunig时只需在脚本中载入预训练好的model,脚本代码:
../../caffe-master_github/build/tools/caffe train \
-solver ./VGG_ILSVRC_19_layers_sovler.prototxt \
-weights ./VGG_ILSVRC_19_layers.caffemodel \ #载入预训练的model
2>&1 | tee log.txt