昨天晚上博主干到12点多,终于用了一晚上时间搞定了Faster-Rcnn训练自己的数据集,这篇博客介绍如何用faster_rcnn训练自己的数据集,前提是已经准备好了自己的数据和配置好了faster-rcnn的环境。
制作数据集教程:http://blog.youkuaiyun.com/gybheroin/article/details/72581318
环境配置教程:http://blog.youkuaiyun.com/gybheroin/article/details/72428582
请大家自行前往查看。
1、把自己的数据集放到Faster-master中
我觉得这个过程是最重要的一个过程吧,博主在这里跳了很多的坑,最后找到了一个非常简单高效的方法。不用修改任何文件,就可以轻松实现加载自己的数据集。
在faster_rcnn-master文件夹下,有一个datasets文件夹,把VOCdevkit2007文件夹放在datasets文件夹下,然后在VOCdevkit2007文件夹下把你的数据集文件夹拷进去,并把你的数据集文件夹命名为VOC2007。通过这种方式可以最大限度的减少路径修改的麻烦。当然,如果你不想这样做,就需要修改faster_rcnn-master\datasets\VOCdevkit2007\VOCcode\VOCinit.m
不采用命名VOC2007的方法就要把这几个路径修改成自己的路径。
2、修改数据标签
在faster_rcnn-master\datasets\VOCdevkit2007\VOCcode\VOCinit.m中把标签修改成自己的标签
if VOC2006
% VOC2006 classes
VOCopts.classes={...
'bicycle'
'bus'
'car'
'cat'
'cow'
'dog'
'horse'
'motorbike'
'person'
'sheep'};
else
% VOC2007 classes
VOCopts.classes={...
'person' %修改成自己的标签
};
end
3、修改验证参数
function\fast_rcnn\fast_rcnn_train.m和function\rpn\proposal_train.m中,
ip.addParamValue('val_iters', 56, @isscalar); %原来的值是500
ip.addParamValue('val_interval', 2000, @isscalar);
据说这个地方是根据数据集来的,是验证集的1/5,博主没有试过不修改是什么情况,感兴趣的同学可以不修改对比有什么差别。
4、网络模型参数的修改
models\ fast_rcnn_prototxts\ZF\ train_val.prototxt models文件中默认的应该是空文件夹,这个模型大小1.4G,我没法上传,所以大家先去网上找找下载一下,如果找不到联系我我再把需要的文件发给你。
input: "bbox_targets"
input_dim: 1 # to be changed on-the-fly to match num ROIs
input_dim: 8 # 根据类别数改,该值为(类别数+1)*4
input_dim: 1
input_dim: 1
input: "bbox_loss_weights"
input_dim: 1 # to be changed on-the-fly to match num ROIs
input_dim: 8 # 根据类别数改,该值为(类别数+1)*4
input_dim: 1
input_dim: 1
layer {
bottom: "fc7"
top: "cls_score"
name: "cls_score"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
type: "InnerProduct"
inner_product_param {
num_output: 2 #根据类别数改该值为类别数+1
layer {
bottom: "fc7"
top: "bbox_pred"
name: "bbox_pred"
type: "InnerProduct"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
inner_product_param {
num_output: 8 #根据类别数改,该值为(类别数+1)*4
faster_rcnn-master\models\fast_rcnn_prototxts\ZF\test.prototxt
layer {
bottom: "fc7"
top: "cls_score"
name: "cls_score"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
type: "InnerProduct"
inner_product_param {
num_output: 2 #根据类别修改!类别数+1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
bottom: "fc7"
top: "bbox_pred"
name: "bbox_pred"
type: "InnerProduct"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
inner_product_param {
num_output: 8 #根据类别修改!(类别数+1)*4
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}
models\ fast_rcnn_prototxts\ZF_fc6\ train_val.prototxt
input: "bbox_targets"
input_dim: 1 # to be changed on-the-fly to match num ROIs
input_dim: 8 # 4*(类别数+1) 因为我只标注了一个类
input_dim: 1
input_dim: 1
input: "bbox_loss_weights"
input_dim: 1 # to be changed on-the-fly to match num ROIs
input_dim: 8 # 4*(类别数+1)
input_dim: 1
input_dim: 1
layer {
bottom: "fc7"
top: "cls_score"
name: "cls_score"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
type: "InnerProduct"
inner_product_param {
num_output: 2 #类别数+1
layer {
bottom: "fc7"
top:"bbox_pred"
name:"bbox_pred"
type:"InnerProduct"
param {
lr_mult:1.0
}
param {
lr_mult:2.0
}
inner_product_param{
num_output: 8 #(类别数+1)*4
models\ fast_rcnn_prototxts\ZF_fc6\ test.prototxt
layer {
bottom: "fc7"
top: "cls_score"
name: "cls_score"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
type: "InnerProduct"
inner_product_param {
num_output: 2 类别数+1
layer {
bottom: "fc7"
top: "bbox_pred"
name: "bbox_pred"
type: "InnerProduct"
param {
lr_mult: 1.0
}
param {
lr_mult: 2.0
}
inner_product_param {
num_output: 8 #(类别数+1) *4
5、solver文件的更改
solver文件的更改在faster_rcnn-master\experiments+Model\ZF_for_Faster_RCNN_VOC2007.m
model.stage1_rpn.solver_def_file = fullfile(pwd, 'models', 'rpn_prototxts', 'ZF', 'solver_30k40k.prototxt'); %solver_60k80k.prototxt可以修改不同的solver文件
model.stage1_rpn.test_net_def_file = fullfile(pwd, 'models', 'rpn_prototxts', 'ZF', 'test.prototxt');
model.stage1_rpn.init_net_file = model.pre_trained_net_file;
6、开始训练
打开faster_rcnn-master\experiments\script_faster_rcnn_VOC2007_ZF.m,切换到faster_rcnn-master目录,开始训练。
补充:
如果出现测试精度为0的情况,需要在imdb\imdb_eval_voc.m中做以下修改
%do_eval = (str2num(year) <= 2007) | ~strcmp(test_set,'test');
do_eval = 1;