利用自己的数据集使用VGG16训练Faster R-CNN
目录
3.6修改train_net.py(运行train_net.py进行训练时修改)
3.7修改config.py(运行train_net.py进行训练时修改)
3.8修改faster_rcnn_end2end.sh(采用脚本训练时修改)
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
- DL学习之 2 —— Faster R-CNN 训练自己的数据集遇到的问题总结
- 使用faster rcnn训练自己的数据(py-faster-rcnn )
- py-faster-rcnn+GPU的编译安装以及训练自己的数据集
- py-faster-rcnn+CPU训练自己的数据集(一)
- faster rcnn在自己的数据集上训练
- windows faster r-cnn制作自己的数据集并训练
- 使用py-faster-rcnn训练自己的数据集
- py-faster-rcnn + cpu安装及训练自己的数据集
- 使用caffe框架利用faster-rcnn来训练自己的数据集
- 使用Faster R-CNN训练自己的数据_NWPU_VHR-10数据集
- py-faster-rcnn + cpu安装及训练自己的数据集
- Faster RCNN 实践篇 - 使用 resnet 做预训练,Kitti 数据集做 fine-tuning,训练一个目标检测模型
- 使用Faster R-CNN训练自己的数据
- py-faster-rcnn+CPU训练自己的数据集(二)
- 仿照VOC2007制作自己的数据集,并在Caffe上训练Faster-RCNN
- 使用labelIImg制作自己的数据集(VOC2007格式)用于Faster-RCNN训练
- Faster RCNN 训练自己的数据集(Matlab,python版本)及制作VOC2007格式数据集
- 使用faster rcnn训练自己的数据-制作数据集
- 使用faster rcnn训练自己的模型
- faster rcnn训练自己的数据集demo和训练过程error总结