论文:DeRPN: Taking a further step toward more general object detection(AAAI2019)
链接:https://arxiv.org/pdf/1811.06700.pdf
代码:https://github.com/HCIILAB/DeRPN
解读:https://mp.weixin.qq.com/s/4nJGdV3qF4IsfxLM8BBeqg
该文提出了一种基于维度分解的候选区域提取方法(dimension-decomposition region proposal network,DeRPN)
1:把目标的宽高解耦来分解检测维度,从而减轻目标形状变化对检测造成的影响。
2:可避免传统RPN网络对不同任务需要进行合适的anchor box调参问题,是一种更加通用的目标检测候选区域提取方法。
3:在不修改任何超参数、不做特别优化的情况下可直接应用于不同的任务和数据集上,具有极强的自适应性。
一、研究背景
目前的检测算法并非很通用,运用于不同的数据集时,通常不可避免地要对它们的回归参考(regression references,在RPN中也叫做anchor boxes)进行重新设计。其主要原因在于RPN中的anchor boxes过于敏感,限制了检测算法的自适应性。为此,提出了维度分解的候选区域提取网络,引入新颖的anchor strings来替代传统的anchor boxes,以提升检测算法的自适应性。
二、DeRPN原理简述
图1、DeRPN的网络结构和流程
如图所示,DeRPN包含维度分解和维度重组两个步骤。维度分解中,我们引入anchor strings机制,让目标的宽高独立地与anchor strings进行匹配,以寻求最佳的回归参考。其中,每个anchor string只需要独立地应对数据集中目标宽(高)的n种变化即可,而先前的anchor box则要应对n2种目标框的变化。因此,通过这种维度分解,我们可以极大地降低匹配复杂度(O(n2)-->O(n))。
为了将所预测的线段恢复成二维的候选区域(region proposal),我们需要做维度重组。论文提出了pixel-wise combination algorithm的维度重组算法,这种无监督的高效组合算法,可以让DeRPN精确地召回检测目标。
参考文献
[1] Ren, S.; He, K.; Girshick, R.; and Sun, J. 2015. Faster r-cnn: Towards real-time object detection with region proposal networks. In NIPS, 91–99.
-----------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------2019.05.27更新---------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------
论文宣称的效果还不错,尝试在pva-lite网络结构上试试效果。
在linux上 git clone半天也下载不下来,好在win上有shaowsock,所以可以配置一下,就可以愉快的下载了
配置
git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'
取消配置
方式一:通过git取消代理设置
$ git config --global --unset http.proxy
$ git config --global --unset https.proxy
方式二:
export http_proxy=""
export https_proxy=""
export HTTP_PROXY=""
export HTTPS_PROXY=""
方式三:通过系统命令取消代理
$ unset http_proxy
$ unset ftp_proxy
$ unset all_proxy
$ unset https_proxy
$ unset no_proxy
本以为把里面的faster-rcnn里面的VGG的网络结构,替换成pva-lite的网络结构就可以愉快的跑起来,是我想的太简单了。
问题(1):需要将里面的层进行相应的替换【参考DeRPN里面提供的VGG网络结构就可以】
有个细节需要注意:num_output都要更改成28 【2*2N不再是以前的2*N,4*N】,论文中有具体的解释【具体就是下面3处】
layer {
name: "rpn_cls_score"
type: "Convolution"
bottom: "rpn_conv1"
top: "rpn_cls_score"
param { lr_mult: 1 decay_mult: 1 }
param { lr_mult: 2 decay_mult: 0 }
convolution_param {
num_output: 28#50
kernel_size: 1 stride: 1 pad: 0
weight_filler { type: "gaussian" std: 0.01 }
bias_filler { type: "constant" value: 0 }
}
}
layer {
name: "rpn_bbox_pred"
type: "Convolution"
bottom: "rpn_conv1"
top: "rpn_bbox_pred"
param { lr_mult: 1 decay_mult: 1 }
param { lr_mult: 2 decay_mult: 0 }
convolution_param {
num_output: 28#100
kernel_size: 1 stride: 1 pad: 0
weight_filler { type: "gaussian" std: 0.01 }
bias_filler { type: "constant" value: 0 }
}
}
layer {
name: 'rpn_cls_prob_reshape'
type: 'Reshape'
bottom: 'rpn_cls_prob'
top: 'rpn_cls_prob_reshape'
reshape_param { shape { dim: 0 dim: 28 dim: -1 dim: 0 } }
}
修改好的网络结构可以从这里下载:
https://download.csdn.net/download/lilai619/11208956
问题(2):vgg里面没有downsample, upsample,pva-lite里面有,所以会出现feature-map大小老是对不上的错误
原因:
vgg是直筒结构,derpn是单尺度训练,所以也不会遇到这个问题。
pva是多尺度训练,每张图都会缩放成32的倍数,所以pva-lite结构中是不会遇到这个问题。
所以:
将pva的尺度处理拿过来就可以解决这个问题。
具体操作:
(1)blob.py中修改prep_im_for_blob函数
def prep_im_for_blob(im, pixel_means, target_size, max_size, multiple):
"""Mean subtract and scale an image for use in a blob."""
im = im.astype(np.float32, copy=False)
im -= pixel_means
im_shape = im.shape
im_size_min = np.min(im_shape[0:2])
im_size_max = np.max(im_shape[0:2])
im_scale = float(target_size) / float(im_size_min)
# Prevent the biggest axis from being more than MAX_SIZE
if np.round(im_scale * im_size_max) > max_size:
im_scale = float(max_size) / float(im_size_max)
im_scale_x = np.floor(im.shape[1] * im_scale / multiple) * multiple / im.shape[1]
im_scale_y = np.floor(im.shape[0] * im_scale / multiple) * multiple / im.shape[0]
im = cv2.resize(im, None, None, fx=im_scale_x, fy=im_scale_y,
interpolation=cv2.INTER_LINEAR)
return im, np.array([im_scale_x, im_scale_y, im_scale_x, im_scale_y])
(2)minibatch.py
# blobs['im_info'] = np.array(
# [[im_blob.shape[2], im_blob.shape[3], im_scales[0]]],
# dtype=np.float32)
替换成
blobs['im_info'] = np.array(
[np.hstack((im_blob.shape[2], im_blob.shape[3], im_scales[0]))],
dtype=np.float32)
#im, im_scale = prep_im_for_blob(im, cfg.PIXEL_MEANS, target_size,
#cfg.TRAIN.MAX_SIZE)
替换成
im, im_scale = prep_im_for_blob(im, cfg.PIXEL_MEANS, target_size,
cfg.TRAIN.MAX_SIZE, 32)
问题(3):如何添加多尺度训练呢?
(1)修改faster_rcnn_derpn_end2end.yml文件
EXP_DIR: faster_rcnn_derpn_end2end
TRAIN:
HAS_RPN: True
IMS_PER_BATCH: 1
BBOX_NORMALIZE_TARGETS_PRECOMPUTED: True
RPN_POSITIVE_OVERLAP: 0.7
RPN_BATCHSIZE: 256
PROPOSAL_METHOD: gt
BG_THRESH_LO: 0.0
SCALE_MULTIPLE_OF: 32
MAX_SIZE: 1440
SCALES:
- 512
- 544
- 576
- 608
- 640
- 672
- 704
- 736
- 768
- 800
- 832
- 864
- 896
- 928
- 960
- 992
- 1024
TEST:
HAS_RPN: True
# EXP_DIR: faster_rcnn_derpn_end2end
# TRAIN:
# HAS_RPN: True
# IMS_PER_BATCH: 1
# BBOX_NORMALIZE_TARGETS_PRECOMPUTED: True
# RPN_POSITIVE_OVERLAP: 0.7
# RPN_BATCHSIZE: 256
# PROPOSAL_METHOD: gt
# BG_THRESH_LO: 0.0
# TEST:
# HAS_RPN: True
(2)修改config.py文件[添加下面的代码]
# Resize test images so that its width and height are multiples of ...
__C.TRAIN.SCALE_MULTIPLE_OF = 1
(3)修改minibatch.py文件
im, im_scale = prep_im_for_blob(im, cfg.PIXEL_MEANS, target_size,
cfg.TRAIN.MAX_SIZE, 32)
将前面需改的32替换成cfg.TRAIN.SCALE_MULTIPLE_OF,即
im, im_scale = prep_im_for_blob(im, cfg.PIXEL_MEANS, target_size,
cfg.TRAIN.MAX_SIZE, cfg.TRAIN.SCALE_MULTIPLE_OF)
开心的跑起来,多尺度如下框,现在是单卡单batch训练,效果好的话,再添加到多卡多batch框架里面。
贴一下训练日志: