首先要安装 caffe 和 pycaffe,安装过程可参考我的上一篇博文
在安装并运行 Faster R-CNN demo,训练和测试自己的 VOC 数据集中也出现了各种各样的问题,但大多数问题都是因为 Faster R-CNN 本身和其他各种依赖项之间的兼容问题,大概是因为我安装的 CUDA,cuDNN 等其他一些依赖项的版本比较高造成的。
Faster R-CNN 安装并运行 demo
其 Github 上也有比较详细的安装过程可供参考,传送门:
1. 下载 Faster R-CNN,编译 Cython 模块
git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git cd py-faster-rcnn/lib make
2. 创建 Makefile.config 文件,打开并修改,修改方式和 Caffe 中的修改方式一样,可参考我的上一篇博文
cd py-faster-rcnn/caffe-fast-rcnn cp Makefile.config.example Makefile.config
替换 py-faster-rcnn/caffe-fast-rcnn/include/caffe/util 里的 cudnn.hpp 为最新版 caffe 里的 cudnn.hpp
替换 py-faster-rcnn/caffe-fast-rcnn/include/caffe/layers 里以 cudnn 开头的文件为最新版 caffe 里以 cudnn 开头的文件
否则会报 cudnn 版本不兼容的问题
3. 编译 Caffe 和 pycaffe
cd py-faster-rcnn/caffe-fast-rcnn
make -j8 && make pycaffe
4. 下载预计算的 Faster-RCNN 检测器模型,有它才可以实现 demo 中的检测
cd $FRCN_ROOT ./data/scripts/fetch_faster_rcnn_models.sh
5. 运行 demo
cd py-faster-rcnn ./tools/demo.py
如果成功运行会弹出几张图片,上面会框出被识别的区域并标明其类别。
训练和测试 VOC 格式数据集
首先需要准备好 VOC 格式的数据集,不管是网上下载的还是自己准备,这里只针对 VOC 格式数据集的训练和测试。
训练和测试步骤参考了 Github 上关于 Faster-RCNN 的另一篇 tutorial,传送门。
1. 建立数据集的软链接
假设 Py-Faster-RCNN 的根目录为 $PY_FASTER_RCNN,在 PY_FASTER_RCNN/data 文件夹中建立链接到数据集的软链接,例如我创建了 example_devkit 文件夹,在example_devkit 文件夹中创建 data 文件夹,并建立其到数据集的软链接,假设数据集文件夹名为 example,命令如下:
ln -s <数据集的文件路径>/example $PY_FASTER_RCNN/data/example_devkit/data
2. 添加 lib/datasets/yourdatabase.py 文件
在 $PY_FASTER_RCNN 下,添加 lib/datasets/yourdatabase.py 文件,因为数据集是 VOC 的格式,所以我结合了原 Faster-RCNN repository 中 lib/datasets/pascal_voc.py 文件和那个 tutorial repository 中 lib/datasets/inria.py 文件,来修改了我添加的文件 example.py。以下是几处主要修改的地方,我先对 inria.py 进行了修改:
1) self._classes 处添加数据集的类别,是背景加上其他类别的总数量
2) 指向数据集中图片和 ImageSets 文件夹的路径 image_path 和 image_set_file 的修改
3) 引用 pascal_voc.py 中的 _load_pascal_annotation 函数替代原 _load_inria_annotation 函数
4) 一些细节上的修改,函数名,import 包等
3. 更新 lib/datasets/factory.py 文件
添加如下代码
from datasets.example import example example_devkit_path = ‘$PY_FASTER_RCNN/data/example_devkit‘ for split in [‘train‘, ‘test‘]: name = ‘{}_{}‘.format(‘example‘, split) __sets[name] = (lambda split=split: example(split, eample_devkit_path))
4. 修改网络模型
以 ZF 模型的 alternated optimizations 为例,复制原模型文件到新的 example 文件夹中并修改
cd $PY_FASTER_RCNN/models/ mkdir example cp -r pascal_voc/ZF/faster_rcnn_alt_opt/ example/
主要是对模型的类别进行修改,比如我的数据集有8类,修改 faster_rcnn_test.pt,stage1_fast_rcnn_train.pt,stage2_fast_rcnn_train.pt,stage2_rpn_train.pt 每个文件中原21处为8(总共要修改7处)
修改 faster_rcnn_test.pt,stage1_fast_rcnn_train.pt,stage2_fast_rcnn_train.pt 每个文件中原 84 处为32(4*8,总共要修改3处)
此外,还需修改 stage1_fast_rcnn_solver30k40k.pt,stage2_fast_rcnn_solver30k40k.pt,stage2_rpn_solver60k80k.pt 每个文件中 train_net 的路径为新的路径,例如 models/example/faster_rcnn_alt_opt/stage1_fast_rcnn_train.pt
5. 在 $PY_FASTER_RCNN 下创建模型的 config.yml 文件
echo ‘MODELS_DIR: "$PY_FASTER_RCNN/models"‘ >> config.yml
6. 开始训练
在 $PY_FASTER_RCNN 目录下输入以下命令进行训练:
./tools/train_faster_rcnn_alt_opt.py --gpu 0 --net_name example --weights data/imagenet_models/ZF.v2.caffemodel --imdb example_train --cfg config.yml
其中 data/imagenet_models/ZF.v2.caffemodel 为需要下载的预训练的 ImageNet 模型,可运行如下命令下载,可能会因为网速下不下来,那就要另找途径了。。。
cd $PY_FASTER_RCNN ./data/scripts/fetch_imagenet_models.sh
可以先用小的迭代次数测试训练是否顺利,将 py-faster-rcnn/tools/train_faster_rcnn_alt_opt.py 中的迭代次数(第81行)改变为被注释的 max_iters = [100, 100, 100, 100],先让试着训练一次。如果一切顺利,那就可以直接放大的迭代次数就可以了,这样会比较节省时间一点。训练中可能会出现一些问题,解决方式参考文章末节的 ‘训练过程中的问题和解决方式’。
7. 测试
训练结束之后将 $PY_FASTER_RCNN/output/default/train 中的最终模型 example_faster_rcnn_final.caffemodel 拷贝到 data/faster_rcnn_models 中,在 tools/ 文件夹下新建 demo_example.py 文件,添加修改后的 demo.py 文件的内容, 主要修改包括
1) 修改类别
CLASSES = (‘__background__‘, ‘class1‘,‘class2‘, ...,‘classn‘)
2) 修改NET名称
NETS = {‘vgg16‘: (‘VGG16‘, ‘VGG16_faster_rcnn_final.caffemodel‘),
‘zf‘: (‘ZF‘, ‘example_faster_rcnn_final.caffemodel‘)}
3) 修改 prototxt 文件的路径
prototxt = ‘$PY_FASTER_RCNN/models/example/faster_rcnn_alt_opt/faster_rcnn_test.pt‘
4) 添加要测试的图片的文件名
im_names = [‘example1.jpg‘,‘example2.jpg‘, ..., ‘examplen.jpg‘]
在 $PY_FASTER_RCNN 下,运行 example.py
./tools/example.py --net zf
训练过程中的问题和解决方式
1. ‘module‘ object has no attribute ‘text_format‘
在文件 /lib/fast_rcnn/train.py 增加一行 import google.protobuf.text_format
2. ‘numpy.float64‘ object cannot be interpreted as an index
1) /home/xxx/py-faster-rcnn/lib/roi_data_layer/minibatch.py
将第26行:fg_rois_per_image = np.round(cfg.TRAIN.FG_FRACTION * rois_per_image)
改为:fg_rois_per_image = np.round(cfg.TRAIN.FG_FRACTION * rois_per_image).astype(np.int)
2) /home/xxx/py-faster-rcnn/lib/datasets/ds_utils.py
将第12行:hashes = np.round(boxes * scale).dot(v)
改为:hashes = np.round(boxes * scale).dot(v).astype(np.int)
3) /home/xxx/py-faster-rcnn/lib/fast_rcnn/test.py
将第129行: hashes = np.round(blobs[‘rois‘] * cfg.DEDUP_BOXES).dot(v)
改为: hashes = np.round(blobs[‘rois‘] * cfg.DEDUP_BOXES).dot(v).astype(np.int)
4) /home/xxx/py-faster-rcnn/lib/rpn/proposal_target_layer.py
将第60行:fg_rois_per_image = np.round(cfg.TRAIN.FG_FRACTION * rois_per_image)
改为:fg_rois_per_image = np.round(cfg.TRAIN.FG_FRACTION * rois_per_image).astype(np.int)
3. slice indices must be integers or None or have an __index__ method
修改 /home/XXX/py-faster-rcnn/lib/rpn/proposal_target_layer.py,转到123行:
for ind in inds: cls = clss[ind] start = 4 * cls end = start + 4 bbox_targets[ind, start:end] = bbox_target_data[ind, 1:] bbox_inside_weights[ind, start:end] = cfg.TRAIN.BBOX_INSIDE_WEIGHTS return bbox_targets, bbox_inside_weights
这里的 ind,start,end 都是 numpy.int 类型,这种类型的数据不能作为索引,所以必须对其进行强制类型转换,转化结果如下:
for ind in inds: ind = int(ind) cls = clss[ind] start = int(4 * cos) end = int(start + 4) bbox_targets[ind, start:end] = bbox_target_data[ind, 1:] bbox_inside_weights[ind, start:end] = cfg.TRAIN.BBOX_INSIDE_WEIGHTS return bbox_targets, bbox_inside_weight
原文:https://www.cnblogs.com/ToBeDeveloper-Zhen/p/9097997.html