Relation Networks for Object Detection源码解读(网络结构细节)

本文深入探讨了Relation Networks for Object Detection的源码,重点关注网络结构的改进,特别是如何在Faster RCNN的基础上加入relation module。通过解析关键方法如get_symbol、extract_position_matrix、extract_position_embedding和attention_module_multi_head,揭示了ROI Pooling之后的全连接层如何引入object relation module,并介绍了坐标变换、坐标embedding和关系特征的计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

论文:Relation Networks for Object Detection
论文链接:https://arxiv.org/abs/1711.11575
代码链接:https://github.com/msracver/Relation-Networks-for-Object-Detection

这篇文章的细节可以通过阅读源码来加深理解,这篇博客就来介绍这篇文章的部分源码。

因为这篇文章主要是在网络结构上做改动,所以这篇博客以resnet_v1_101_rcnn_attention_1024_pairwise_position_multi_head_16_learn_nms.py为例介绍网络结构,这个例子在Faster RCNN基础上引入relation module,包括全连接层和NMS阶段。

链接:resnet_v1_101_rcnn_attention_1024_pairwise_position_multi_head_16_learn_nms.py

接下来介绍的代码顺序和链接中的不大一样,这里按照代码运行时的顺序介绍,目的是方便跟着数据流进行阅读,主要涉及几个方法:全局网络构造:get_symbol;ROI信息的坐标变换:extract_position_matrix;ROI信息的坐标embedding:extract_position_embedding;object relation module的计算:attention_module_multi_head。

这里将网络结构封装成一个类,初始化函数中主要是resnet_v1_101网络的设置。

class resnet_v1_101_rcnn_attention_1024_pairwise_position_multi_head_16_learn_nms(resnet_v1_101_rcnn_learn_nms_base):
    def __init__(self):
        """
        Use __init__ to define parameter network needs
        """
        self.eps = 1e-5
        self.use_global_stats = True
        self.workspace = 512
        self.units = (3, 4, 23, 3)  # use for 101
        self.filter_list = [256, 512, 1024, 2048]

get_symbol方法是获取网络结构时候调用的方法,也是这个脚本中的主干,接下来都会围绕该方法进行介绍。在该方法中包含了整体网络结构的构造,非常重要。提取说明下,在ROI Pooling层之前的结构基本上和Faster RCNN类似,重点在于ROI Pooling层后面的两个全连接层。

def get_symbol(self, cfg, is_train=True):

        # config alias for convenient
# 首先是一个参数设定。以COCO数据集为例(这篇文章的实验都是在COCO数据集上做的),
# num_classes是81。cfg.CLASS_AGNOSTIC参数表示回归时是否不区分类别,默认是True,
# 也就是不区分类别,因此num_reg_classes默认是2。需要注意的是原生的Faster RCNN在
# 回归时是区分类别的。num_anchors默认是12,这个数值比原生的Faster RCNN要大。
        num_classes = cfg.dataset.NUM_CLASSES
        num_reg_classes = (2 if cfg.CLASS_AGNOSTIC else num_classes)
        num_anchors = cfg.network.NUM_ANCHORS

        # input init
# 输入数据和信息的初始化,需要和数据读取的变量同名。
        if is_train:
            data = mx.sym.Variable(name="data")
            im_info = mx.sym.Variable(name="im_info")
            gt_boxes = mx.sym.Variable(name="gt_boxes")
            rpn_label = mx.sym.Variable(name='label')
            rpn_bbox_target = mx.sym.Variable(name='bbox_target')
            rpn_bbox_weight = mx.sym.Variable(name='bbox_weight')
        else:
            data = mx.sym.Variable(name="data")
            im_info = mx.sym.Variable(name="im_info")

        # shared convolutional layers
# conv_feat,包含resnet_v1_101从开始到conv4结束,这一部分是RPN网络的输入。
# relu1,包含resnet_v1_101从开始到conv5结束,用来做object的坐标回归和分类。这都是常规的做法。
        conv_feat = self.get_resnet_v1_conv4(data)
        # res5
        relu1 = self.get_resnet_v1_conv5(conv_feat)

# 这部分是基于conv_feat,调用get_rpn方法得到rpn网络的输出。
        rpn_cls_score, rpn_bbox_pred = self.get_rpn(conv_feat, num_anchors)

        if is_train:
            # prepare rpn data
            rpn_cls_score_reshape = mx.sym.Reshape(
                data=rpn_cls_score, shape=(0, 2, -1, 0), name="rpn_cls_score_reshape")

            # classification
# 这部分是对bbox的二分类损失函数。
            rpn_cls_prob = mx.sym.SoftmaxOutput(data=rpn_cls_score_reshape, label=rpn_label, multi_output=True, normalization='valid', use_ignore=True, ignore_label=-1, name="rpn_cls_prob")

            # bounding box regression
# 这部分是对bbox的坐标回归损失函数。
            rpn_bbox_loss_ = rpn_bbox_weight * mx.sym.smooth_l1(name='rpn_bbox_loss_', scalar=3.0, data=(rpn_bbox_pred - rpn_bbox_target))

            rpn_bbox_loss = mx.sym.MakeLoss(name='rpn_bbox_loss', data=rpn_bbox_loss_, grad_scale=1.0 / cfg.TRAIN.RPN_BATCH_SIZE)

            # ROI proposal
# 这部分是对bbox做过滤得到proposal。注意几个参数:1、cfg.TRAIN.RPN_PRE_NMS_TOP_N表示
# 进行NMS操作之前的roi数量,默认是6000。2、cfg.TRAIN.RPN_POST_NMS_TOP_N表示
# NMS操作之后的roi操作,默认是300(FPN网络中默认用1000)。这两个参数设置和Faster RCNN不同。
# 3、cfg.network.ANCHOR_SCALES默认是4,8,16,32。
# 4、cfg.network.ANCHOR_RATIOS默认是0.5,1,2。
            rpn_cls_act = mx.sym.SoftmaxActivation(
                data=rpn_cls_score_reshape, mode="channel", name="rpn_cls_act")
            rpn_cls_act_reshape = mx.sym.Reshape(
                data=rpn_cls_act, shape=(0, 2 * num_anchors, -1, 0), name='rpn_cls_act_reshape')
            if cfg.TRAIN.CXX_PROPOSAL:
                rois = mx.contrib.sym.Proposal(
                    cls_prob=rpn_cls_act_reshape, bbox_pred=rpn_bbox_pred, im_info=im_info, name='rois', feature_stride=cfg.network.RPN_FEAT_STRIDE, scales=tuple(cfg.network.ANCHOR_SCALES), ratios=tuple(cfg.network.ANCHOR_RATIOS),                    rpn_pre_nms_top_n=cfg.TRAIN.RPN_PRE_NMS_TOP_N, rpn_post_nms_top_n=cfg.TRAIN.RPN_POST_NMS_TOP_N,                    threshold=cfg.TRAIN.RPN_NMS_THRESH, rpn_min_size=cfg.TRAIN.RPN_MIN_SIZE)
            else:
                rois = mx.sym.Custom(
                    cls_prob=rpn_cls_act_reshape, bbox_pred=rpn_bbox_pred, im_info=im_info, name='rois', op_type='proposal', feat_stride=cfg.network.RPN_FEAT_STRIDE,
scales=tuple(cfg.network.ANCHOR_SCALES), ratios=tuple(cfg.network.ANCHOR_RATIOS),
                    rpn_pre_nms_top_n=cfg.TRAIN.RPN_PRE_NMS_TOP_N, rpn_post_nms_top_n=cfg.TRAIN.RPN_POST_NMS_TOP_N,                    threshold=cfg.TRAIN.RPN_NMS_THRESH, rpn_min_size=cfg.TRAIN.RPN_MIN_SIZE)

# ROI proposal target
# 这部分一方面对前面的propsoal做过滤得到batch_rois个proposal(或者叫roi),最后
# 得到的rois数量由cfg.TRAIN.BATCH_ROIS决定,这里因为cfg.TRAIN.BATCH_ROIS默认
# 是-1(和Faster RCNN中默认的128不同),因此最后得到的roi数量等于输入roi的数量加
# 上ground truth的数量,默认情况下输入roi数量是300,因此最后得到的roi数量是300+x,
# x表示object的数量。另一方面计算Fast RCNN的分类和回归支路的训练目标。
            gt_boxes_reshape = mx.sym.Reshape(data=gt_boxes, shape=(-1, 5), name='gt_boxes_reshape')
            rois, label, bbox_target, bbox_weight = mx.sym.Custom(rois=rois, gt_boxes=gt_boxes_reshape, op_type='proposal_target', num_classes=num_reg_classes, batch_images=cfg.TRAIN.BATCH_IMAGES, batch_rois=cfg.TRAIN.BATCH_ROIS, cfg=cPickle.dumps(cfg),
fg_fraction=cfg.TRAIN.FG_FRACTION)
        else:
# 这部分是测试时候的网络结构设置,总体而言就是去掉了RPN网络的损失函数和Fast RCNN的
# 分类和检测目标生成等。
            # ROI Proposal
            rpn_cls_score_reshape = mx.sym.Reshape(
                data=rpn_cls_score, shape=(0, 2, -1, 0), name="rpn_cls_score_reshape")
            rpn_cls_prob = mx.sym.SoftmaxActivation(
                data=rpn_cls_score_reshape, mode="channel", name="rpn_cls_prob")
            rpn_cls_prob_reshape = mx.sym.Reshape(
                data=rpn_cls_prob, shape=(0, 2 * num_anchors, -1, 0), name='rpn_cls_prob_reshape')
            if cfg.TEST.CXX_PROPOSAL:
                rois = mx.contrib.sym.Proposal(
                    cls_prob=rpn_cls_prob_reshape, bbox_pred=rpn_bbox_pred, im_info=im_info, name='rois', feature_stride=cfg.network.RPN_FEAT_STRIDE, scales=tuple(cfg.network.ANCHOR_SCALES), ratios=tuple(cfg.network.ANCHOR_RATIOS),
rpn_pre_nms_top_n=cfg.TEST.RPN_PRE_NMS_TOP_N, rpn_post_nms_top_n=cfg.TEST.RPN_POST_NMS_TOP_N,
threshold=cfg.TEST.RPN_NMS_THRESH, rpn_min_size=cfg.TEST.RPN_MIN_SIZE)
            else:
                rois = mx.sym.Custom(
                    cls_prob=rpn_cls_prob_reshape, bbox_pred=rpn_bbox_pred, im_info=im_info, name='rois', op_type='proposal', feat_stride=cfg.network.RPN_FEAT_STRIDE,
scales=tuple(cfg.network.ANCHOR_SCALES), ratios=tuple(cfg.network.ANCHOR_RATIOS),
rpn_pre_nms_top_n=cfg.TEST.RPN_PRE_NMS_TOP_N, rpn_post_nms_top_n=cfg.TEST.RPN_POST_NMS_TOP_N,
threshold=cfg.TEST.RPN_NMS_THRESH, rpn_min_size=cfg.TEST.RPN_MIN_SIZE)

# nongt_dim在训练中采用cfg.TRAIN.RPN_POST_NMS_TOP_N,默认是300,这个值在后续会经常用到。
        nongt_dim = cfg.TRAIN.RPN_POST_NMS_TOP_N if is_train else cfg.TEST.RPN_POST_NMS_TOP_N

# 接下来这个卷积层是接在conv5后面的。
        conv_new_1 = mx.sym.Convolution(data=relu1, kernel=(1, 1), num_filter=
### 回答1: "few-shot object detection with attention-rpn and multi-relation detector" 是一种使用注意力机制的少样本目标检测方法。它通过使用 Attention-RPN(Region Proposal Network)和 Multi-Relation Detector 来实现对目标的检测。 Attention-RPN 可以在提议区域中识别关键部位,而 Multi-Relation Detector 则可以在少量样本中识别目标并定位它们。这种方法在训练和测试时都需要少量样本,因此可以减少模型的训练时间和资源消耗。 ### 回答2: 随着人工智能技术的不断发展,目标检测的研究也得到了越来越多的关注。其中,Few-shot object detection with attention-rpn and multi-relation detector是目前在目标检测领域上的一个最新研究成果。那这个算法是什么呢? 针对目前目标检测领域中的一大难点——少样本学习,此研究提出了一种基于RPN(region proposal network)和注意力机制的多关系检测算法,使得模型只需使用少量的训练数据,就能在未见过的类别中达到较高的检测准确率。 具体来说,该算法通过在RPN中引入注意力交互模块来提供精细的检测区域,同时通过设计多组关系特征提取器,能够有效处理不同目标类别之间的相互关系。在训练阶段,该算法将训练数据集划分为meta-train和meta-test集合,然后在较小的meta-train集合中学习关系特征提取器和注意力交互模块,最后在meta-test集合的未知类别中进行目标检测。 综合以上基本思路,该算法通过引入注意力机制和多关系特征提取器来实现Few-shot object detection。该算法在目前的Few-shot目标检测基准测试数据集上进行了实验证明,实现了较高的检测准确率,在很大程度上解决了少样本学习的问题。未来,这个技术还需要进一步实践和推广,使得得到更广泛的使用。 ### 回答3: 本文介绍了一种基于注意力机制RPN(Attention-RPN)和多关系检测器(Multi-Relation Detector)的小样本目标检测技术(Few-shot Object Detection)。该技术可以利用预训练的模型来辅助小样本检测任务,并可以适应新的目标类别。 本文中的Attention-RPN是一种针对小样本学习的改进版本,它可以通过选择性的关注训练数据中的重要区域来提高小样本的性能。同时,Attention-RPN还可以利用先前训练模型的知识来指导小样本的训练过程,从而提高检测结果的准确性。 而多关系检测器则是一种可以检测目标之间关系的模型。通过学习目标之间的关系,可以更好地理解图像中的场景,并且可以更准确地定位和分类目标。本文中的多关系检测器采用了一种新的模型结构,其中用到了一种称为Transformers的自注意力机制,它可以自适应地聚焦于任务中的关键区域,从而提高检测性能。 在实验中,本文采用了COCO、VOC和miniImagenet等数据集进行测试。结果表明,本文所提出的Few-shot Object Detection技术可以在少量样本的情况下取得好的检测结果。同时,Attention-RPN和Multi-Relation Detector也能分别提高小样本和多样本的检测性能,证明它们是十分有效的模型改进方式。 综上所述,本文提出了一种新的小样本目标检测技术,并通过Attention-RPN和Multi-Relation Detector的改进来提高检测性能。该技术对于具有高效率和精度要求的目标检测任务具有十分重要的意义,可能对未来的计算机视觉研究和工业应用产生积极的影响。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值