您的位置:首页 > Web前端

基于caffe在已有模型上进行微调finetune

2017-08-22 09:04 218 查看
近期要对医学图像在caffe上进行微调,总算找到一篇不错的文章,转载过来,方便查阅。

网址:http://www.cnblogs.com/denny402/p/5137534.html

caffe团队用imagenet图片进行训练,迭代30多万次,训练出来一个model。这个model将图片分为1000类,应该是目前为止最好的图片分类model了。

假设我现在有一些自己的图片想进行分类,但样本量太小,可能只有几百张,而一般深度学习都要求样本量在1万以上,因此训练出来的model精度太低,根本用不上,那怎么办呢?

那就用caffe团队提供给我们的model吧。

因为训练好的model里面存放的就是一些参数,因此我们实际上就是把别人预先训练好的参数,拿来作为我们的初始化参数,而不需要再去随机初始化了。图片的整个训练过程,说白了就是将初始化参数不断更新到最优的参数的一个过程,既然这个过程别人已经帮我们做了,而且比我们做得更好,那为什么不用他们的成果呢?

使用别人训练好的参数,必须有一个前提,那就是必须和别人用同一个network,因为参数是根据network而来的。当然,最后一层,我们是可以修改的,因为我们的数据可能并没有1000类,而只有几类。我们把最后一层的输出类别改一下,然后把层的名称改一下就可以了。最后用别人的参数、修改后的network和我们自己的数据,再进行训练,使得参数适应我们的数据,这样一个过程,通常称之为微调(fine tuning).

既然前两篇文章我们已经讲过使用digits来进行训练和可视化,这样一个神器怎么能不使用呢?因此本文以此工具为例,讲解整个微调训练过程。

一、下载model参数

可以直接在浏览器里输入地址下载,也可以运行脚本文件下载。下载地址为:http://dl.caffe.berkeleyvision.org/bvlc_reference_caffenet.caffemodel

文件名称为:bvlc_reference_caffenet.caffemodel,文件大小为230M左右,为了代码的统一,将这个caffemodel文件

下载到caffe根目录下的 models/bvlc_reference_caffenet/ 文件夹下面。也可以运行脚本文件进行下载:

# sudo ./scripts/download_model_binary.py models/bvlc_reference_caffenet


二、准备数据
如果有自己的数据最好,如果没有,可以下载我的练习数据:http://pan.baidu.com/s/1MotUe

这些数据共有500张图片,分为大巴车、恐龙、大象、鲜花和马五个类,每个类100张。编号分别以3,4,5,6,7开头,各为一类。我从其中每类选出20张作为测试,其余80张作为训练。因此最终训练图片400张(放在train文件夹内,每个类一个子文件夹),测试图片100张(放在test文件夹内,每个类一个子文件夹)。

将图片下载下来后解压,放在一个文件夹内。比如我在当前用户根目录下创建了一个data文件夹,专门用来存放数据,因此我的训练图片路径为:/home/xxx/data/re/train

三、设置model

caffenet的网络配置文件,放在 caffe/models/bvlc_reference_caffenet/ 这个文件夹里面,名字叫train_val.prototxt。

打开这个文件,将里面的内容复制到上图的Custom Network文本框里,然后进行修改,主要修改这几个地方:

1、修改train阶段的data层为:

layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
mirror: true
crop_size: 227
}
}


即把均值文件(mean_file)、数据源文件(source)、批次大小(batch_size)和数据源格式(backend)这四项都删

除了。因为这四项系统会根据dataset和页面左边“solver options"的设置自动生成。

2、修改test阶段的data层:

layer {
name: "data"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
mirror: false
crop_size: 227
}
}


和上面一样,也是删除那些项。

3、修改最后一个全连接层(fc8):

layer {
name: "fc8-re"               #原来为"fc8"
type: "InnerProduct"
bottom: "fc7"
top: "fc8"
param {
lr_mult: 1.0
decay_mult: 1.0
}
param {
lr_mult: 2.0
decay_mult: 0.0
}
inner_product_param {
num_output: 5        #原来为"1000"
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0.0
}
}
}


看注释的地方,就只有两个地方修改,其它不变。

设置好后,就可以开始微调了(fine tuning).

训练结果就是一个新的model,可以用来单张图片和多张图片测试。具体测试方法前一篇文章已讲过,在此就不重复

了。

在此,将别人训练好的model用到我们自己的图片分类上,整个微调过程就是这样了。只需要修改一个

train_val.prototxt的配置文件就可以了,其它都是一样的操作。

方法二

参照http://blog.csdn.net/u012878523/article/details/41698209的说明,完成了在caffe上利用自己的数据集进行微调,现在将整个过程记录如下。

一.准备数据集 

1.准备原始数据集 

数据集中包括训练集和测试集。我是在caffe-windows主目录下新建了lp文件夹,里面有train和val两个文件夹。train里面又有pos_train和neg_train两个文件夹,分别存放着用于训练的正样本和负样本(各有500张256*256的图片)。val文件夹里面存放着100张图片。

2.制作标签txt文件 

这一步我们需要对数据集中的图片添加标签,然后存成txt文件。由于我对matlab比较熟悉,所以用matlab编写了相应的程序,如下:
pos_folder="your path";
neg_folder = "your path";
image_width = 120;   %图像小块的宽度
image_height = 34;  %图像小块的高度
pixel_total = image_width * image_height*3; %图像中像素点的数目
pos = dir(pos_folder);

[pos_row,pos_line] = size(pos);
neg = dir(neg_folder);
[neg_row,neg_line] = size(neg);
fid=fopen('train.txt','w');
for i=3:pos_row
img_name = [pos_folder,pos(i).name];
[a,b]=strtok(img_name,pos_folder);
d=strcat(a,b);
d=strcat('train_pos/',d);
fprintf(fid,'%s %d\n',d,1);
end

for i=3:neg_row
img_name = [neg_folder,neg(i).name];
[a,b]=strtok(img_name,neg_folder);
d=strcat(a,b);
d=strcat('train_neg/',d);
fprintf(fid,'%s %d\n',d,2);
end
fclose(fid);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

上述程序生成的train.txt内容如下:



同理可制作val.txt,如下所示:



3.利用caffe把数据集转换成leveldb的格式 

打开maincaller.cpp,编译convert_imageset.cpp.,

然后在caffe主目录下建立一个convert.bat文件,内容如下: 

SET GLOG_logtostderr=1 

bin\MainCaller.exe data/lp/train/ data/lp/train.txt data/lp/mtrainlb 0 

pause

双击convert.bat即可生成mtrainlb文件夹,这里面存放的就是leveldb格式的数据。

二.开始微调自己的网络 

首先选择编译fine_tune.cpp,生成maincaller.exe

我直接使用的是imagenet的网络结构,所以将examples/imagenet里面的imagenet_train.prototxt、imagenet_val.prototxt、imagenet_solver.prototxt直接拷过来修改一下。 

imagenet_train.prototxt、imagenet_val.prototxt改动的地方主要是: 
source:mtrainlb 
fc8的输出改成2层

接下来同样创建一个finetune.bat文件,内容如下: 

copy ..\..\bin\MainCaller.exe ..\..\bin\fintune.exe 

SET GLOG_logtostderr=1 

“../../bin/fintune.exe” imagenet_solver.prototxt caffe_reference_imagenet_model 

pause

然后双击运行,一开始的时候报错: 
mtrainldb文件中的:MANIFEST-000007句柄无效的提示 

然后程序就崩溃了。

在这个问题上折腾了很多时间,最后仔细观察命令行的打印信息才发现: 

我这边出现这个问题的原因是train.protxt和test.protxt会使用同一个leveldb文件,因此会重复打开而失败。我就把mtrainldb复制了一下,重命名为mtrainldb2,然后把val.protxt里面的source改成mtrainldb2就好了。

接下来双击fine_tune.exe就可以开始微调了。CNN的训练方面目前接触比较少,接下来会研究CNN训练的一些trick 参数等等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: