pytorch 1.0实现faster R-CNN
简介
这个工程实战是***在Ubuntu***系统上基于jwyang发布在github上的faster R-CNN点我链接。其模型是基于***pytorch 1.0.0***开发的,请注意自己的版本号。在这篇文章中将实现检测自己的Pascal_VOC数据集。由于这不是基础教学,所以不涉及到pytorch的安装,相关内容请参考其他博文。
总结一下我的实现环境:Ubuntu16.04、 CUDA10.0、 pytorch1.0.0、torchvision 0.2.1、python3.5。
Step1、安装
首先是clone代码:
git clone https://github.com/jwyang/faster-rcnn.pytorch.git
这里如果你和我一样用的是pytorch1.0及其以上版本需要切换git分支到torch1.0版本,因此接着输入:
git checkout pytorch-1.0
这一句相当重要,千万不要忘了!!!否则会导致后续很多错误。
完成git分支切换后,按照顺序输入以下命令配置依赖的环境:
#进入faster-rcnn.pytorch文件,同时在内创建一个data文件夹
cd faster-rcnn.pytorch && mkdir data
#安装依赖的pyhon包,这一步若是报错说没有权限访问安装就在开头加上 sudo
pip install -r requirements.txt
#下载coco kit,并make
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
make
完成后将终端回退到faster-rcnn.pytorch目录下,在进入到lib文件夹内:
cd lib
python setup.py build develop
这里如果遇到ffi已弃用:
ImportError: torch.utils.ffi is deprecated. Please use cpp extensions instead
说明没有将faster R-CNN的版本更换到pytorch 1.0版本。你需要在git clong源代码后使用git checkout pytorch-1.0命令切换分支。
如果你成功执行到到这里,那么依赖环境的配置就已经完成了,接着就可以开始训练自己的数据集啦。
有的同学可能想立马开始测试一下刚下载的模型,很遗憾这时候还不可以,因为作者只提供了特征提取层的权重,没有后面分类、回归等的参数,所以无法直接进行测试。除非你有别人训练好的,那可以拷贝过来直接测试。
Step2、下载特征提取层的预训练(pre-trained)权重
作者给出了两种特征提取网络的Pretrained Models,这里也给出下载链接:
Step3、训练前的其他准备
1)、准备数据集
在完成上面的步骤后,我们就可以开始准备开手着手训练了。那么首先准备自己的数据集,我此次用的是Pascal_VOC类型的数据集。这里不对Pascal_VOC数据集的制作进行详细阐述,只捡几个重点说:
- 1、VOC数据集的文件夹tree结构:其中Annotations内放xml标注文件,JPEGImages内放图片,ImageSets/Main/内的四个txt文件分别是测试集、训练集、训练验证集、验证集。
注意训练时所用的集合是trainval,而不是train。
VOCdevkit
└── VOC2007
├── Annotations
├── ImageSets
│ └── Main
│ ├── test.txt
│ ├── train.txt
│ ├── trainval.txt
│ └── val.txt
└── JPEGImages
- 2、数据集标注格式
***我们需要的Pascal_VOC数据集的标注格式是1-Based(就是坐标原点是从(1,1)开始的而不是0,0)!!!***这一点相当重要,因为如果错误基于(0,0)为坐标原点的话会导致:
assert (boxes[:, 2] >= boxes[:, 0]).all()
该错误意思是ROI框的xmin比xmax大,ymin比ymax大,或者根本没有bndbox属性,导致错误的代码段是lib/datasets/pascal_voc.py 的line:235~241行:
for ix, obj in enumerate(objs):
bbox = obj.find('bndbox')
# Make pixel indexes 0-based
x1 = float(bbox.find('xmin').text) - 1
y1 = float(bbox.find('ymin').text) - 1
x2 = float(bbox.find('xmax').text) - 1
y2 = float(bbox.find('ymax').text) - 1
既如果标注格式是基于(0,0)的那么如果有ROI框的xmin或ymin在0位置就会导致减1越界变为了65535>>xmax/ymax。
当然造成该错误的因素还有可能是:bndbox的坐标超过了图片的宽高(标注错误,或未作图片的正畸校验)。
其解决方法参考Blog:
faster rcnn:assert (boxes[:, 2] >= boxes[:, 0]).all()分析塈VOC2007 xml坐标定义理解
assert (boxes[:, 2] >= boxes[:, 0])错误解决方法
2)、修改相关代码
- 1、修改lib/datasets/pascal_voc.py文件的48~53行中的类别为自己的类:
self._classes = ('__background__', # always index 0
'aeroplane', 'bicycle', 'bird', 'boat',
'bottle', 'bus', 'car', 'cat', 'chair',
'cow', 'diningtable', 'dog', 'horse',
'motorbike', 'person', 'pottedplant',
'sheep', 'sofa', 'train', 'tvmonitor')
'''将其中的类别改为自己的类,但是注意不要动background那个类别,其用于RPN阶段softmax的二分类'''
- 2、修改 trainval_net.py中60~61行中save_dir的保存地址,将default=“models”中的models改为自己的路径:
parser.add_argument('--save_dir', dest='save_dir',
help='directory to save models', default="models",
Step4、开始训练
在/faster-rcnn.pytorch目录中打开终端,输入命令
CUDA_VISIBLE_DEVICES=0 python trainval_net.py --dataset pascal_voc --net res101 \
--epochs 20 --bs 1 --nw 4 --lr 1e-2 --lr_decay_step 8 --use_tfb \
--mGPUs --cuda
参数的意义:
- CUDA_VISIBLE_DEVICES=0:用0号GPU
- –dataset pascal_voc:用pascal数据集
- –net res101:用res101作为特征提取网络,可选vgg16
- –epochs 20:20个epoch,每个epoch都过一遍全部的训练图。
- –bs 1:batch_size=1
- –nw 4:num_works=4,4线程进行读取,我的显卡显存是11G,如果显存小的话就设为1
- –lr 1e-2: 初始学习率是0.01;可选参数
- –lr_decay_step 8: 每几个epoch学习率衰减一次(默认衰减一次0.1,通过decay_gamma可调);可选参数
- –use_tfb: 使用tensorboardX实现记录和可视化,不用就不写;可选参数
- –mGPUs: 多GPU训练,不用就不写该命令;可选参数
- –cuda:使用cuda;
说明: 每一个batch 过一遍所有训练图,迭代次数iterations取决于batch_size和图片数量决定,比如有2000张图batch_size = 4,则iterations = 2000 / 4 = 500。
运行成功后,终端会输出:
usr@usr:~/faster-rcnn.pytorch$ CUDA_VISIBLE_DEVICES=0,1 python trainval_net.py --dataset pascal_voc --mGPUs --net res101 --bs 1 --nw 4 --cuda
Called with args:
Namespace(batch_size