[目标检测]论文翻译&代码理解-SCRDet: Towards More Robust Detection for Small, Cluttered and Rotated Objects

本文详细介绍了目标检测算法SCRDet,该算法通过Finer Sampling and Feature Fusion Network (SF-Net)、Multi-Dimensional Attention Network和Rotation Branch增强对小、杂乱和旋转物体的检测能力。SF-Net通过精细采样和特征融合处理小物体特征不足的问题,MDA-Net则采用监督学习的多维注意力机制减少噪声信息,Rotation Branch利用旋转分支提升角度预测的准确性。文章探讨了各组件的设计原理,并给出了相关代码段落。
摘要由CSDN通过智能技术生成

2019.12.10 更新 未完结
在这里插入图片描述

3. The Proposed Method

首先,我们在图1中概述了我们的两阶段方法:
在第一阶段,通过添加SF-Net和MDA-Net,可以期望特征图包含更多的特征信息和更少的噪声。为了角度参数的位置灵敏度,此阶段仍使水平框回归。
通过改进的五参数回归和第二阶段中每个提案的旋转非最大抑制(R-NMS)操作,我们可以获得任意旋转下的最终检测结果。

3.1 Finer Sampling and Feature Fusion Network (SF-Net)

在我们的分析中,检测小物体有两个主要障碍:物体特征信息不足和anchor样本不足。 原因是由于使用池化层,因此小对象在深层中丢失了大部分特征信息。 同时,高级特征图的较大采样步幅倾向于直接跳过较小的对象,从而导致采样不足。

3.1.1 Feature fusion

通常认为,低级特征图可以保留小对象的位置信息,而高级特征图可以包含高级语义线索。 特征金字塔网络(FPN)[23],自上而下调制(TDM)[35]和与对象先验网络(RON)的反向连接[21]是常见的特征融合方法,涉及高低级特征图不同形式的组合。

3.1.2 Finer sampling

训练样本不足和不平衡会影响检测性能。 通过引入期望的最大重叠(EMO)得分,[45]中的作者计算出锚点和物体之间的期望的最大联合交叉点(IoU)。 他们发现锚点(SA)的stride越小,获得的EMO得分越高,从统计上讲导致所有对象的平均最大IoU均得到改善。
在这里插入图片描述
图2显示了分别跨步16和8进行小物体采样的结果。 可以看出,较小的SA可以对更多高质量的样本进行采样,从而很好地捕获了小物体,这对于检测器训练和推理都非常有帮助。
在这里插入图片描述
基于以上分析,我们设计了更精细的采样和特征融合网络(SF-Net),如图3所示。在基于锚点的检测框架中,特征图相对于原始图像缩减了 S A S_A SA倍。换句话说, S A S_A SA的值只能是2的指数倍。SF-Net通过更改特征图的大小来解决此问题,从而使SA的设置更加灵活以允许更多自适应采样。为了减少网络参数,SF-Net仅使用Resnet [16]中的C3和C4进行融合,以平衡语义信息和位置信息,同时忽略其他不太相关的功能。简单来说,SF-Net的第一个通道会对C4进行升采样,以使其SA = S,其中S是预期的锚跨度。第二个通道还将C3上采样到相同的大小。然后,我们将C3传递给起始结构,以扩展C3的接受域并增加语义信息。初始结构包含各种比率卷积核以捕获对象形状的多样性。最后,通过将两个通道逐个元素相加获得新的特征图F3。
在这里插入图片描述
表1列出了不同SA下DOTA的检测精度和训练开销。我们发现最佳的SA取决于特定的数据集,尤其是小对象的大小分布。在本文中,为了在精度和速度之间进行权衡,通常将S的值设置为6。

——此处代码在代码 ./libs/networks/resnet.py (test部分)
def resnet_base(img_batch, scope_name, is_training=True):
    '''
    this code is derived from light-head rcnn.
    https://github.com/zengarden/light_head_rcnn
    It is convenient to freeze blocks. So we adapt this mode.
    '''
    if scope_name == 'resnet_v1_50':
        middle_num_units = 6
    elif scope_name == 'resnet_v1_101':
        middle_num_units = 23
    else:
        raise NotImplementedError('We only support resnet_v1_50 or resnet_v1_101 or mobilenetv2. '
                                  'Check your network name.')

    blocks = [resnet_v1_block('block1', base_depth=64, num_units=3, stride=2),
              resnet_v1_block('block2', base_depth=128, num_units=4, stride=2),
              # use stride 1 for the last conv4 layer.
              resnet_v1_block('block3', base_depth=256, num_units=middle_num_units, stride=1)]
              # when use fpn, stride list is [1, 2, 2]

    with slim.arg_scope(resnet_arg_scope(is_training=False)):
        with tf.variable_scope(scope_name, scope_name):
            # Do the first few layers manually, because 'SAME' padding can behave inconsistently
            # for images of different sizes: sometimes 0, sometimes 1
            net = resnet_utils.conv2d_same( img_batch, 64, 7, stride=2, scope='conv1')
            net = tf.pad(net, [[0, 0], [1, 1], [1, 1], [0, 0]])
            net = slim.max_pool2d( net, [3, 3], stride=2, padding='VALID', scope='pool1')

    not_freezed = [False] * cfgs.FIXED_BLOCKS + (4-cfgs.FIXED_BLOCKS)*[True]
    # Fixed_Blocks can be 1~3

    with slim.arg_scope(resnet_arg_scope(is_training=(is_training and not_freezed[0]))):
        C2, end_points_C2 = resnet_v1.resnet_v1(net,
                                                blocks[0:1],
                                                global_pool=False,
                                                include_root_block=False,
                                                scope=scope_name)

    with slim.arg_scope(resnet_arg_scope(is_training=(is_training and not_freezed[1]))):
        C3, end_points_C3 = resnet_v1.resnet_v1(C2,
                                                blocks[1:2],
                                                global_pool=False,
                                                include_root_block=False,
                                                scope=scope_name)

    with slim.arg_scope(resnet_arg_scope(is_training=(is_training and not_freezed[2]))):
        C4, _ = resnet_v1.resnet_v1(C3,
                                    blocks[2:3],
                                    global_pool=False,
                                    include_root_block=False,
                                    scope=scope_name)

        if cfgs.ADD_FUSION:
            C3_shape = tf.shape(end_points_C3['{}/block2/unit_3/bottleneck_v1'.format(scope_name)])
            C4 = tf.im
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值