本文是基于以下两篇文章的综合,大多数内容也是这两篇文章的,只是同时结合了自己在实际操作的时候一些感悟,感谢以下两篇文章!
出处:https://www.cnblogs.com/wind-chaser/p/11359521.html
出处:https://blog.csdn.net/ThunderF/article/details/100294913
本文是作者的第一篇CSDN博客,有什么问题请及时联系,谢谢!主要是用来记录下自己平时学习的东西,错误的地方还请各位大佬指正!
torch版本:1.0.1
Python版本:3.6/3.7
torchvision版本:0.2.1
需要OpenCV3、matplotlib、numpy等
Ubuntu16.04
CUDA版本:9.0及其以上
GPU型号:GTX1080及其以上(测试用的是TITAN XP)
我们先将faster-rcnn的仓库克隆到本地,这里使用的是jwyang
的faster-rcnn.pytorch。此处是在Ubuntu上进行操作,若要在windows上操作,需要先安装Git,这个可以参考廖雪峰的Git教程。
git clone -b pytorch-1.0 --single-branch --depth=1 --recursive https://github.com/jwyang/faster-rcnn.pytorch.git
git clone -b 分支名 --single-branch: 是克隆指定分支的命令,因为需要克隆的模型是pytorch1.0的faster-rcnn,而master下的faster-rcnn是0.4版本的,所以需要到pytorch-1.0下去克隆。
–depth==1: 是指克隆最近一次更改,因为将整个仓库克隆下来可能会因为仓库太大而报错无法克隆。
–recursive: 用于循环递归克隆子项目
cd
定位到faster-rcnn.pytorch
,并创建data文件夹
cd faster-rcnn.pytorch
mkdir data
定位到data
,下载压缩文件到data
,此处用的数据集是VOC2007。
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar
linux系统中会自带wget,Windows环境下需要下载。
随后,解压数据到data/VOCdevkit
tar xvf VOCtrainval_06-Nov-2007.tar
tar xvf VOCtest_06-Nov-2007.tar
tar xvf VOCdevkit_08-Jun-2007.tar
创建软链接
cd faster-rcnn.pytorch/data
ln -s VOCdevkit的绝对路径 VOCdevkit2007
此处我并没有如此创建软链接,而是参照ThunderF的修改名字的操作,即直接将VOCdevkit改成VOCdevkit2007
PASCAL VOC 2010 and 2012、COCO等数据集也是如此操作
此处有VGG16和ResNet101两个预训练模型可供下载
VGG16:
①Dropbox
②VT Server
ResNet101:
①Dropbox
②VT Server
基于caffe训练的模型要比基于pytorch训练的模型表现好些,我是下载的Dropbox,不过需要科学上网。
下载完以后,把这两个模型都放进/data/pretrained_model/
(需要创建pretrained_model这个文件夹)里。
首先cd
到/faster-rcnn.pytorch
,使用pip命令安装所有的python依赖包:
pip install -r requirements.txt
其次,使用下面的命令编译CUDA依赖环境
cd lib
python setup.py build develop
在训练之前,设置 正确的保存和加载模型的目录,改变trainval_net
和test_net.py
中的参数save_dir
和loader_dir
以适应你的环境。
使用vgg16
/res101
在pascal_voc
上训练你的faster-rcnn
模型,运行下面代码
CUDA_VISIBLE_DEVICES=0 python trainval_net.py --dataset pascal_voc --net res101 --epochs 5 --bs 4 --lr 0.001 --lr_decay_step 5 –cuda
其中,
CUDA_VISIBLE_DEVICES: 指代gpu的id
- -dataset: 指代数据集名称,我们就以pascal-voc为例
- -net: 指代你的backbone网络是啥,我们以res101为例
- -bs: 指的batch size。默认为1。bs切记不要太大,本例中bs=16会爆12G的显存,如果出现如下报错,调小bs即可。(在此引用的是wind-chaser的图片)
- -nw: 指的是worker number,取决于你的Gpu能力,我用的是Titan Xp 12G,所以选择4。稍微差一些的gpu可以选小一点的值。
- -lr: 是学习率,太大可能会出现nan
的情况
(我在实际操作的时候,发现lr=0.01
的时候就出现过这个错误,lr=0.001
就没有问题,另外,附上遇到这种问题的一些解决方法:https://www.jianshu.com/p/b7347e1dc615
)
- -cuda: 指的是使用gpu。
若是在服务器上长久运行,断掉连接关掉xshell后继续运行,可是使用nohup
和&
语句。
nohup python trainval_net.py --dataset pascal_voc --net res101 --epochs 5 --bs 4 --lr 0.001 --lr_decay_step 5 --cuda &
注意: 当在Linux系统上运行nohup
和&
语句后,一定要用exit
退出,这样才是真正成功挂上,使得程序在后台继续运行。
正常情况下(反正我是遇到过…),进行训练的时候,会出现以下两个错误:
1、报can not import _mask
等类似的错误,大概是coco编译环境错误,结合https://github.com/jwyang/faster-rcnn.pytorch/issues/410
中的方法,解决如下:
cd data
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
make
随后删掉faster-rcnn.pytorch/lib
里面的pycocotool
文件夹,重新运行编译即可
cd lib
python setup.py build develop
2、出现can’t import ‘imread’
,请检查scipy的版本是否超过了1.0,因为1.0以上的版本里,scipy不再使用imread
。解决如下:
pip uninstall scipy
pip install scipy==1.0
并且推荐更改pillow版本为5.2.0。而且scipy和pillow要在同一路径下(如果上面的scipy解决后没问题,可不执行这个操作)
pip uninstall pillow
pip install pillow==5.2.0
如果你想要估计vgg16
/resnet101
的预训练模型在pascal_voc
测试集上的表现,运行以下代码即可
python test_net.py --dataset pascal_voc --net res101 --checksession $SESSION --checkepoch $EPOCH --checkpoint $CHECKPOINT –cuda
要指定具体的checksession
、checkepoch
、checkpoint
数值。如果你不知该如何设置,可以根据你训练出来的模型名字来设置。
此处借用[2]ThunderF
的结果,例如:
checksession
= 1,checkepoch
= 1, checkpoint
= 10021;则
python test_net.py --dataset pascal_voc --net res101 --checksession 1 –checkepoch1 --checkpoint 10021 –cuda
测试集5000张图像,一块TITANX平均测试时间0.1s/张,占用显存5G左右
测试结果:
在VOC上20个class的mAP为为70%,实际训练12epoch能到75%左右,
如果你想要运行预训练模型去检测你自己的图片,要先下载预训练模型或者训练你自己模型,然后把图片放到工作目录下的images
文件夹里。
我们测试的图片都在images
文件夹里。在此处有坑。作者提供了4张image做测试,因为测试完的图像会输出到images
文件夹里,所以做完一次测试,images文件夹会有8张图片(输出图片命名规则是在原图像文件名后面加上_det
),而原作者没有把他自己测试后的图片删去,所以大家在做demo测试时,别忘把以_det
结尾的检测输出文件先删去,否则测试完你的images
文件夹可能会得到16张图像。
当然,你可以放一些你自己在网上搜的图片在images
文件夹里进行demo测试,看看效果。但检测类别一定在训练的类别中要有啊。
VOC2007数据集的类别在路径/faster-rcnn.pytorch/lib/datasets/pascal_voc.py
文件中已注明,在此处提醒:
运行demo的命令:
python demo.py --net res101 --checksession 1 –checkepoch1 --checkpoint 10021 –cuda --load_dir models
除了指定那三个数值外,还要写清楚存放net101/pascal_voc/模型.pth
的文件夹—models
**
由于我暂时手头没有合适的数据集,故这部分内容基本上是借用如下文章的
作者:wind-chaser;
出处:https://www.cnblogs.com/wind-chaser/p/11359521.html
作者:ThunderF;
出处:https://blog.csdn.net/ThunderF/article/details/100294913
**
我们仍然采用VOC2007数据集的类。皮不变,只是把我们自己的数据集“塞进去”。真正“起作用”的训练集其实是这四个文件夹,位置是:faster-rcnn.pytorch/data/VOCdevkit/VOC2007/
1.Annotations 为标注文件夹,若干.xml文件。每一个图片都对应一个.xml文件,其中存储的是该图片的名称,长宽,目标框(GroundTrues)的左上右下坐标,目标框的类别名称。所以我们也要把该文件夹下的xml文件替换为自己的。
2.ImagesSet文件夹下的Main里,保存了需要训练图片的名称,以txt文本存储。
3.JPEGImage文件夹保存了训练图片。
首先把我们的训练图片放进进JPEGImage文件夹里。该文件夹下原来的图片我们需要备份,并从JPEGImage里移除。
然后将Annotations下的xml文件替换为自己的,原来的xml文件备份后从该文件夹下移除。需要制作我们自己数据集的xml标注文件,如果想问做出的xml文件标准是啥样的,因为不同的标注软件生成的标注文件五花八门,和VOC一样的xml文件怎么制作?在此给个传送门:
https://blog.csdn.net/gvfdbdf/article/details/52214008
https://blog.csdn.net/zcy0xy/article/details/79614862
在此也给出如何更改xml文件中属性值的方法,用这个代码可以任意改变xml里的属性值,比如你想把xml文件中类别名称改变,或把图片名称、路径等值改变,链接如下:
https://github.com/XinZhangNLPR/Xml-document-modify.git
接着我们自己制作trainval.txt
文件,即将trainval.txt
文件里的图片名称替换为自己的图片名称,具体请看图:
制作好后将该文件放入ImagesSet\Main
中,替换掉原有的trainval.txt
。
①修改lib\datasets\pascal_voc.py
中的类别信息,即把原来的类别换成你要训练的类别。如
这个文件里存着VOC数据库的class
,需要更改我们识别的类别,我的做法是把原class
注释掉,把自己的class
加进去,如图,加入plane
类,看到这你也许就知道啦,这里的类名和前面xml文件中,目标的name
属性应该是一样的。
②发生如下错误:
assert(boxes[:,2]>=boxes[:,0]).all()
基本上都会碰上,只要是你标注的框靠近边缘,都会出这个错误,解决措施:
https://blog.csdn.net/xzzppp/article/details/52036794
https://blog.csdn.net/10km/article/details/64641322
③发生如下错误:
Keyerror:'width'
该句指的是得到的图像数据库imdb文件没有’width'
,也就是没有读到图像的宽度值,而这个宽度值是通过图片读出来的,所以说明你的训练文件夹’JPEGImage'
中没有’ImagesSet\Main\trainval.txt'
里列出的图片,我查了下,图片都放进去了,那为啥还出错呢?
原因是在训练原数据集VOC时,图像数量是10021张(进行了数据增强),这时会保存训练信息至缓存中,文件路径为:
’/faster-rcnn.pytorch/data/cache/voc_2007_trainval_gt_roidb.pkl'
因此你在重新训练新数据集的时候,会读取这个缓存配置,以加快训练,那么此时就入坑了,我的新集合只有1000张,所以训练时读的缓存里,需要读的图像还是原来那10021张,那势必会找不到这10021张图像,所以要做的就是,把这个缓存文件’voc_2007_trainval_gt_roidb.pkl'
删掉!
训练命令与前面一致
训练完成后,很想demo一下,看看训出来的模型如何。此处会出现如下错误:
我们会发现,他说我们训的模型,预测层是两个节点(代表2类,飞机+背景),而测试的时候,发现模型是21类(原数据集的类数,20类+背景)。开始以为是训练前网络的输出类别数没有设置好,于是加各种断点找原因,但发现训练时的网络预测的类数就是2类。
需修改’demo.py’文件:跟更改’pascal_voc,py’方法类似,更改自己训练集的类别,如下所示:
接下来,就可以进行正常demo了,有的个别效果不是很好,因为没有调参,而且训练集只有1000张,还没有做数据增强。
万分感谢大家看到这里…第一次写CSDN,请见谅。