目标检测--RFBNet环境配置、训练及验证 (血和泪的教训)

最近接到任务,需要对目标检测进行一下调研。于是我面向GitHub进行了一波编程。经过一番比较发现,RFBNet貌似是非常不错的选择。所以就打算和跟我一样的新手们分享一下经验,也算是记录一下踩过的坑。哪里有错的地方欢迎大佬指出。

关于RFBNet

Receptive Field Block Net for Accurate and Fast Object Detection

这是发表于ECCV2018的目标检测文章,主要贡献是在SSD网络中引入Receptive Field Block (RFB)。RFB结构主要有两个特点:
1、该结构是由多个不同尺寸的卷积核构成的多分枝结构。
2、引入了dilated卷积,增大了感受野。
在这里插入图片描述
论文具体实现的RFB块有以下两种版本:
在这里插入图片描述
其整体结构与SSD一样是基于VGG16的backbone(还有其他版本的,如MobileNet),之所以采用VGG16是因为这是一个比较轻量的骨干网络,在计算速度和精度方面都有很好的表现,这是经过SSD实践的。以下是RFBNet-300的整体结构,此外还有RFBNet-512版本,这里的300和512是输入的尺寸。
在这里插入图片描述
论文给出了基于VOC和COCO数据集的实验结果:
在这里插入图片描述
在这里插入图片描述
结果基本上可以总结为一句话,精度高的没我算的快(能够实时),算的快的没我精度高。
关于论文更多的讲解可以自行百度。。

训练及遇到问题

在大体看完论文后,我就开始了面向GitHub编程了[滑稽]。由于论文是2018年的,官方代码是基于PyTorch0.4.0的,而我装的是1.3.0,想都不用想肯定很多不兼容的。所以我就找了一个基于1.3版本的,开始了一段辛酸路程。

Pytorch1.3版本(失败)

相关配置
pytorch1.3
OpenCV
CUDA-9.2
VOC2007&VOC2012
GTX980 4GB * 4
MobaXterm

首先是克隆一波代码,之后下载数据集。关于数据集的下载,由于COCO太大下载需要很长时间,所以我只在VOC2007和2012上进行了实验。官方给出了下载脚本:

# specify a directory for dataset to be downloaded into, else default is ~/data/
sh data/scripts/VOC2007.sh # <directory>
# specify a directory for dataset to be downloaded into, else default is ~/data/
sh data/scripts/VOC2012.sh # <directory>

但VOC下载官网是在不敢恭维,推荐在这个网站下载之后解压到相应目录即可。

训练及测试

首先需要下载预训练好去全连接层的VGG16权重,将其放到weights目录下。

mkdir weights
cd weights
#如果手动下载VGG16就不需要下面语句
wget https://s3.amazonaws.com/amdegroot-models/vgg16_reducedfc.pth

然后就cd到项目根目录下,运行以下语句开始训练

python train_RFB.py -d VOC -v RFB_vgg -s 300

具体参数的含义就是:
-d VOC 表示使用的数据集,这里是VOC数据集。
-v RFB_vgg 表示是基于VGG,还有RFB_E_VGG和RFB_mobile可选。
-s 300 表示输入尺寸为300,可选512.
当然还可以手动调整其他参数,可以在train_RFB.py中查看。特别地,官方还说明了,对于论文中的精度,在VOC上训练的epoches在240左右,COCO上训练应该是130epoches左右。
由于训练时间较长,建议将程序放入后台运行,关于Linux后台运行程序可以参考这篇博文,对于本程序只需要将以上语句修改成以下形式即可:

nohup python train_RFB.py -d VOC -v RFB_vgg -s 300 &

将程序放入后台之后想看看是否正在运行,可以在终端输入查看GPU占用情况:

nvidia-smi

在这里插入图片描述
可以看到980老干部都已经开始干活了,现在需要做的就是等待结果了。

Two thousand years later…

经过300epoches后终于训练完成,我兴致勃勃的开始进行测试了,之前提到过所以这里选用240轮的训练权重。

python test_RFB.py -d VOC -v RFB_vgg -s 300 --trained_model ./weights/RFB_vgg_VOC_epoches_240.pth

作者给出的结果如下:
在这里插入图片描述
我以为我的结果也能达到差不多的精度,但是现实却泼了一盘冷水。。
出现了CudaCheck的错误信息,但是还能继续跑,最后还出现了Segmentation fault (core dumped),一开始以为没什么关系:
在这里插入图片描述
但是结果却令人沮丧:
在这里插入图片描述
在这里插入图片描述
mAP只有45.92%,跟官方结果差了不是一星半点,还出现了Segmentation fault这种问题,至今还是不明白这是为什么,有知道的大佬请赐教。于是乎我就开始找问题,看大家的解决方法。看到issue区很多人用高版本pytorch在复现的时候都遇到mAP过低的问题,我就想是不是版本间的差异导致的,我一菜鸟也搞不定,所以一狠心就决定再装一个0.4.0的pytorch环境。

PyTorch0.4.0版本(成功)

相关配置
pytorch0.4.0
OpenCV
CUDA-9.2
VOC2007&VOC2012
GTX980 4GB * 4
MobaXterm

首先是创建一个新的虚拟环境避免污染原来环境。

conda create -n pytorch04 python=3.6

这样就创建了一个新的环境,可以运行以下命令查看系统安装的环境。

conda env list

我这里就有原来的环境和新建的pytorch04环境。
创建完之后激活该环境:

source activate pytorch04 #windows 下可能有所不同

激活之后就可以在环境中安装0.4.0版本的pyotrch了。

conda install pytorch=0.4.0 torchvision cuda92
 #或者
pip install torch==0.4.0 torchvision cuda92 -i https://pypi.tuna.tsinghua.edu.cn/simple

关于在Windows安装PyTorch可以参考我之前的博文

训练及测试

在装完pytorch0.4.0之后,就可以训练了。经过一番比较之后,最后还是回到了官方代码哈哈。。
下载代码后,要确保运行的环境是0.4版的,第一次我就搞错了,在1.2环境下运行该代码,结果又是一顿乱错,找了半天才发现,费时费力。。。

首先,运行项目根目录下的make.sh

./make.sh

然后根据自己GPU算力(自行百度)修改utils/build.py中第131行的

'nvcc': ['-arch=sm_52'

之后步骤就与PyTorch1.2版本无异。
下载VGG16预训练权重到weights文件夹中,将VOC2007和2012数据集放到data目录下,安装相应的依赖库。
之后输入以下命令:

python train_RFB.py -d VOC -v RFB_vgg -s 300 

经过20多个小时的训练后进行测试:

python test_RFB.py -d VOC -v RFB_vgg -s 300 --trained_model ./weights/RFB_vgg_VOC_epoches_240.pth

测试过程没有提示任何错误,一路执行下来十分顺畅,最后得出的结果令我泪目:

在这里插入图片描述
在这里插入图片描述
mAP=80.56%与官方的80.7相当接近,很是令我满意!!!

其实官方也提供了预训练好的模型,我也下载了进行了对比测试,结果与我训练的结果基本一致,所以这份代码是可以复现论文结果的。至于1.2版本的代码,我猜测可能是作者实现的时候有缺陷,或者框架本身不同版本底层的实现有差别导致的,这个还得花点精力研究研究。

有什么错误和问题欢迎大家指出交流!

破案了!!! 2020.8.04

之前出现高版本运行mAP过低的情况,后来经过我检查,发现是在./make.sh的时候出现的问题,make.sh的主要作用就是构建nms和pycocotools 。 可能由于新版本的pytorch1.2和utils中用到的编译器版本不一致导致mAP过低。我的解决方法是不用make.sh构建的nms,直接使用github上的基于python的nms程序来进行测试,程序如下:

def nms_py(dets, thresh):
    x1 = dets[:, 0]
    y1 = dets[:, 1]
    x2 = dets[:, 2]
    y2 = dets[:, 3]
    scores = dets[:, 4]

    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    order = scores.argsort()[::-1]
    ndets = dets.shape[0]
    suppressed = np.zeros((ndets), dtype=np.int)
    keep = []
    for _i in range(ndets):
        i = order[_i]
        if suppressed[i] == 1:
            continue
        keep.append(i)
        ix1 = x1[i]
        iy1 = y1[i]
        ix2 = x2[i]
        iy2 = y2[i]
        iarea = areas[i]
        for _j in range(_i + 1, ndets):
            j = order[_j]
            if suppressed[j] == 1:
                continue
            xx1 = max(ix1, x1[j])
            yy1 = max(iy1, y1[j])
            xx2 = min(ix2, x2[j])
            yy2 = min(iy2, y2[j])
            w = max(0.0, xx2 - xx1 + 1)
            h = max(0.0, yy2 - yy1 + 1)
            inter = w * h
            ovr = inter / (iarea + areas[j] - inter)
            if ovr >= thresh:
                suppressed[j] = 1
    return keep

具体就是在test_RFB.py中找到

keep = nms(c_dets, 0.45, force_cpu=args.cpu)

将这一句替换成

keep = nms_py(c_dets, 0.45)

最后测试结果与0.4.0版本的结果一致,说明这个程序是合理的。

由于没有用到COCO,所以pycocotools就暂时不管。

参考

官方代码
https://github.com/ruinmessi/RFBNet/issues/13
RFBNet相关设置
https://www.cnblogs.com/hizhaolei/p/9911029.html
https://blog.csdn.net/u014380165/article/details/81556769
Windows配置pytorch、CUDA及cuDNN
https://www.cnblogs.com/andylhc/p/9721705.html

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值