您的位置:首页 > 其它

利用自己的数据集使用VGG16训练Faster R-CNN

2018-12-18 16:57 549 查看

目录

1建立数据集

1.1图片

1.2xml文件 

1.3数据集划分

2下载ImageNet数据集下预训练得到的模型

3修改prototxt配置文件

3.1修改train.prototxt

3.2修改test.prototxt

3.3修改solver.prototxt

3.4修改pascal_voc.py

3.5修改imdb.py

3.6修改train_net.py(运行train_net.py进行训练时修改)

3.7修改config.py(运行train_net.py进行训练时修改)

3.8修改faster_rcnn_end2end.sh(采用脚本训练时修改)

4.1训练准备

4.2模型训练

4.2.1通过运行脚本命令来训练模型

4.2.2通过运行py文件来训练模型

5测试模型

6Demo

6.1准备

6.2运行Demo

1建立数据集

        数据集格式应和VOC2007相同。

1.1图片

        图片命名按照VOC2007标准格式,如“000001.jpg”形式。训练集中所有的图片重命名后放在路径py-faster-rcnn\data\VOCdevkit2007\VOC2007\JPEGImages下。

1.2xml文件 

        利用labelImg工具对图片自定义绘制包围框,并生成与图片对应的xml文件,如000001.xml。生成的所有的xml文件放在路径py-faster-rcnn\data\VOCdevkit2007\VOC2007\Annotations下。

1.3数据集划分

        利用xml文件划分数据集,生成trainval.txt、train.txt、test.txt和val.txt文件。将生成的四个txt文件放在路径py-faster-rcnn\data\VOCdevkit2007\VOC2007\ImagesSets\Main下。参考下面的python程序:py-faster-rcnn划分数据集(训练集、验证集、训练验证集、测试集)

2下载ImageNet数据集下预训练得到的模型

        运行命令:

[code]  $ cd py-fasyer-rcnn
$ ./data/scripts/fetch_imagenet_models.sh

        下载的model保存在py-fasyer-rcnn /data/文件夹下,名称为imagenet_models。

├── caffe-fast-rcnn              # caffe框架目录

├── data       # 用来存放pretrained模型以及读取文件的cache缓存,还有一些下载模型的脚本

│   ├── cache

│   ├── demo

│   ├── ......

│   ├── scripts

│   ├── VOCdevkit             

│   ├── imagenet_models

│   │   ├── VGG16.v2.caffemodel

│   │   ├── VGG_CNN_M_1024.v2.caffemodel

│   │   └── ZF.v2.caffemodel 

│   └── ......                     

├── experiments                 # 存放配置文件以及运行的log文件

└── .....

3修改prototxt配置文件

        使用基于VGG16模型的近似联合训练方法(端对端)训练和测试Faster R-CNN,需要更改以下配置文件:

3.1修改train.prototxt

     文件路径py-faster-rcnn /models/pascal_voc/VGG16/faster_rcnn_end2end/train.prototxt

①修改input-data层(第11行)

    将原先的num_classes的“21”改成“**”(**为实际类别数+1(背景)):

[code]layer {
name: 'input-data'
type: 'Python'
top: 'data'
top: 'im_info'
top: 'gt_boxes'
python_param {
module: 'roi_data_layer.layer'
layer: 'RoIDataLayer'
param_str: "'num_classes': 21"     //目标类别数+1
}
}

②修改roi-data层(第530行)

    将原先的num_classes的“21”改成“**”(**为实际类别数+1(背景)):

[code]layer {
name: 'roi-data'
type: 'Python'
bottom: 'rpn_rois'
bottom: 'gt_boxes'
top: 'rois'
top: 'labels'
top: 'bbox_targets'
top: 'bbox_inside_weights'
top: 'bbox_outside_weights'
python_param {
module: 'rpn.proposal_target_layer'
layer: 'ProposalTargetLayer'
param_str: "'num_classes': 21"     //目标类别数+1
}
}

③修改cls_score层(第620行)

    将原先的num_classes的“21”改成“**”(**为实际类别数+1(背景)):

[code]layer {
name: "cls_score"
type: "InnerProduct"
bottom: "fc7"
top: "cls_score"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 21     //目标类别数+1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}

④修改bbox_pred层(第643行)

    将原来的num_output的“84”改成“**”(**为(实际类别数+1(背景))*4):

[code]layer {
name: "bbox_pred"
type: "InnerProduct"
bottom: "fc7"
top: "bbox_pred"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 84    //(目标类别数+1)*4
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}

3.2修改test.prototxt

    文件路径py-faster-rcnn /models/pascal_voc/VGG16/faster_rcnn_end2end/test.prototxt。test.prototxt中没有input-data层,只需修改cls_score层和bbox_pred层的方式即可。

①修改cls_score层(第567行)

    将原先的num_classes的“21”改成“**”(**为实际类别数+1(背景)):

[code]layer {
name: "cls_score"
type: "InnerProduct"
bottom: "fc7"
top: "cls_score"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 21     //目标类别数+1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}

②修改bbox_pred层(第592行)

    将原来的num_output的“84”改成“**”(**为(实际类别数+1(背景))*4):

[code]layer {
name: "bbox_pred"
type: "InnerProduct"
bottom: "fc7"
top: "bbox_pred"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 84    //(目标类别数+1)*4
weight_filler {
type: "gaussian"
std: 0.001
}
bias_filler {
type: "constant"
value: 0
}
}
}

3.3修改solver.prototxt

        文件路径py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_end2end/solver.prototxt。该文件可以修改最大迭代次数等。

3.4修改pascal_voc.py

        文件路径py-faster-rcnn/ lib/datasets/pascal_voc.py。这里的类别以及之前的类别名称最好是全部小写,假如是大写的话,则会报keyError的错误。将其中的类别改为自己的。

[code]self._classes = ('__background__',    # always index 0
'car tail', 'car head', 'car turn', 'car crosswide',
'bus tail', 'bus head', 'bus turn', 'bus crosswide',
'truck tail','truck head', 'truck turn', 'truck crosswide',
'person','cyclist', 'cycle','tricycle','barricade','misc')

3.5修改imdb.py

文件路径py-faster-rcnn/lib/datasets/imdb.py。

[code]def append_flipped_images(self):
num_images = self.num_images
# widths = self._get_widths()   # 修改前
widths = [PIL.Image.open(self.image_path_at(i)).size[0]  # 修改后
for i in xrange(num_images)]               # 修改后
for i in xrange(num_images):
boxes = self.roidb[i]['boxes'].copy()
oldx1 = boxes[:, 0].copy()
oldx2 = boxes[:, 2].copy()
boxes[:, 0] = widths[i] - oldx2 – 1
for b in range(len(boxes)):    # 添加
if boxes[b][2] < boxes[b][0]:   # 添加
boxes[b][0] = 0    # 添加
print boxes[:, 0]      ####?
boxes[:, 2] = widths[i] - oldx1 - 1
print boxes[:, 0]      ####?
assert (boxes[:, 2] >= boxes[:, 0]).all()
entry = {'boxes' : boxes,
'gt_overlaps' : self.roidb[i]['gt_overlaps'],
'gt_classes' : self.roidb[i]['gt_classes'],
'flipped' : True}
self.roidb.append(entry)
self._image_index = self._image_index * 2

3.6修改train_net.py(运行train_net.py进行训练时修改)

        文件路径py-faster-rcnn/tools/train_net.py。可以为其中的命令行参数设置默认值,这样就不用每次训练时都在命令行设置多个参数了。

3.7修改config.py(运行train_net.py进行训练时修改)

        文件路径py-faster-rcnn/lib/fast_rcnn/config.py。

        修改:

[code] __C.TRAIN.SNAPSHOT_ITERS=10000

        该参数确定了模型每训练多少次保存一次快照,源码设置的是10000,根据自己设置的最大迭代次数来合理修改(它的值小于最大迭代次数,不然训练了半天一个模型都没保存)。

3.8修改faster_rcnn_end2end.sh(采用脚本训练时修改)

    文件路径:py-faster-rcnn/experiments/scripts/faster_rcnn_end2end.sh

    若调用脚本faster_rcnn_end2end.sh训练模型,则可以在文件中修改最大迭代次数。

[code]  TRAIN_IMDB="coco_2014_train"
TEST_IMDB="coco_2014_minival"
PT_DIR="coco"
ITERS=490000

4模型训练

4.1训练准备

        在训练新模型时候,为防止与之前的模型搞混,需要删除以下文件:

①删除py-faster-rcnn下的output文件夹;

②删除py-faster-rcnn/data/cache中的文件;

③删除py-faster-rcnn/data/VOCdevkit2007/annotations_cache中的文件。

        通过运行命令删除:

[code]  sudo rm -rf ~/py-faster-rcnn/output/*
sudo rm -rf ~/py-faster-rcnn/data/cache/*
sudo rm -rf ~/py-faster-rcnn/data/VOCdevkit2007/annotations_cache/*
sudo rm -rf ~/py-faster-rcnn/data/VOCdevkit2007/results/VOC2007/Main/*

4.2模型训练

4.2.1通过运行脚本命令 20000 来训练模型

[code]  $ cd py-faster-rcnn
$ sudo ./experiments/scripts/faster_rcnn_end2end.sh  0  VGG16  pascal_voc

其中,

  $ sudo  ./experiments/scripts/faster_rcnn_end2end.sh [GPU_ID]  [NET]  [--set ...]

(1)GPU_ID为训练所用的GPU,如果只有一块GPU,则为0;

(2)NET为使用的网络模型,可选择ZF、VGG_CNN_M_1024、VGG16;

(3)--set允许配置fast_rcnn.config文件中的各种选项。

4.2.2通过运行py文件来训练模型

[code]  $ cd py-faster-rcnn
$ sudo python ./tools/train_net.py --gpu 0 --solver models/pascal_voc/VGG16/faster_rcnn_end2end/solver.prototxt --weights data/imagenet_models/VGG16.v2.caffemodel --imdb voc_2007_trainval --cfg experiments/cfgs/faster_rcnn_end2end.yml

        其中,

--gpu:代表机器上的GPU编号。

--solver:代表模型的配置文件,train.prototxt的文件路径已经包含在这个文件之中。

--weights:代表初始化的权重文件,这里用的是Imagenet上预训练好的模型,大型的网络我们选择用VGG_16.v2.caffemodel。

--imdb:给出的训练的数据库名字需要在factory.py的_sets中,在文件里面有_sets[‘hs’],train_net.py:这个文件会调用factory.py再生成hs这个类,来读取数据。

        训练完成后生成的模型保存在路径py-faster-rcnn\output\faster_rcnn_end2end\voc_2007_trainval下。

5测试模型

        运行命令(将vgg16_faster_rcnn_iter_10000.caffemodel修改为自己训练得到的模型):

[code]  $ cd py-faster-rcnn
$ sudo python ./tools/test_net.py --gpu 0 --def models/pascal_voc/VGG16/faster_rcnn_end2end/test.prototxt --net output/faster_rcnn_end2end/voc_2007_trainval/vgg16_faster_rcnn_iter_10000.caffemodel --imdb voc_2007_test --cfg experiments/cfgs/faster_rcnn_end2end.yml

      若测试时出现报错:IndexError:too many indices for array

原因:样本量太少,某些类别在测试集中没有,路径data/VOCdevkit2007/results/VOC2007/main.下生成的对应的txt文件是空的。

解决办法:在路径py-faster-rcnn/lib/datasets/voc_eval.py中的BB=BB[sorted_ind,:]上面一行添加语句if len(BB) !=0:(注意if后要缩进)

6Demo

6.1准备

        训练完成之后,将训练得到的py-faster-rcnn\output\faster_rcnn_end2end\voc_2007_trainval中的caffemodel拷贝至py-faster-rcnn\data\faster_rcnn_models下。

        修改py-faster-rcnn\tools\下demo.py的配置:

(1)修改CLASSES(第27行)

    把里面的原始标签全部改为自己的标签:

[code]CLASSES = ('__background__',
'car tail', 'car head', 'car turn', 'car crosswide',
'bus tail', 'bus head', 'bus turn', 'bus crosswide',
'truck tail','truck head', 'truck turn', 'truck crosswide',
'person','cyclist','cycle','tricycle','barricade','misc')

(2)修改NETS(第39行)

    将VGG16_faster_rcnn_final.caffemodel修改为自己训练得到的模型:

[code]NETS = {'vgg16': ('VGG16',
'VGG16_faster_rcnn_final.caffemodel'),
'zf': ('ZF',
'ZF_faster_rcnn_final.caffemodel'),
'resnet50': ('ResNet-50',
'ResNet-50_faster_rcnn_final.caffemodel')}

(3)修改prototxt(第124行)

    由于prototxt默认配置为faster_rcnn_alt_opt,所以需要修改为faster_rcnn_end2end。

将:

[code]prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
'faster_rcnn_alt_opt', 'faster_rcnn_test.pt')

     修改为:

[code]    prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
'faster_rcnn_end2end', 'test.prototxt')

(4)修改im_names(第148行)

    将内容修改为需要测试的图片名字,并把测试图片放在py-faster-rcnn\data\demo中,并按照训练图片的命名格式和大小来修改测试图片。

    例如测试图片为:

     将:

[code]  im_names = ['000456.jpg', '000542.jpg', '001150.jpg', '001763.jpg', '004545.jpg']

     修改为:

[code]  im_names = ['000001.jpg', '000002.jpg', '000003.jpg', '000004.jpg', '000005.jpg', '000006.jpg']

6.2运行Demo

(1)将默认的模型改为VGG16

    在py-faster-rcnn\tools\demo.py的def parse_args()里修改默认参数:

[code]parser.add_argument (
‘–net’,
dest=’demo_net’,
help=’Network to use [vgg16]’,
choices=NETS.keys(),
default=’vgg16’         # 修改为vgg16
)

(2)运行

运行命令:

[code]  $ cd py-faster-rcnn
$ sudo python ./tools/demo.py

若不修改默认的模型,则运行命令:

[code]  $ cd py-faster-rcnn
$ sudo python ./tools/demo.py  --net vgg16
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: