maskrcnn_benchmark理解记录——modeling\rpn\rpn.py

经过rpn网络得到候选框。是对每一层特征图都用FPN的:

proposals, proposal_losses = self.rpn(images, features, targets)

看下 RPNModule(torch.nn.Module):会返回num_anchors。处理步骤有
1)anchor_generator = make_anchor_generator(cfg)           #生成anchors 可查看rpn\anchor_generator.py
2)registry.RPN_HEADS.register("SingleConvRPNHead") 
  head = rpn_head( cfg, in_channels, anchor_generator.num_anchors_per_location()[0])
添加RPN Head对anchors进行classification and regression。返回值是logits, bbox_reg    这里是对p的各个特征图进行3*3卷积,每个位置都生成结果。
3)对train和test差别处理。(NMS等)保留一定数量的proposals。还是P2~P6每层都一样。来看下数据设置:

    #保留的RPN proposals个数 after combining proposals from all FPN levels
    fpn_post_nms_top_n = config.MODEL.RPN.FPN_POST_NMS_TOP_N_TRAIN  #2000
    if not is_train:
        fpn_post_nms_top_n = config.MODEL.RPN.FPN_POST_NMS_TOP_N_TEST #1000
    #保留的RPN proposals个数 before applying NMS
    #而用FPN的话是指每一个FPN层保留的个数(not total)
    pre_nms_top_n = config.MODEL.RPN.PRE_NMS_TOP_N_TRAIN        #2000
    #applying NMS  那么这里是每一层保留的  还是总的,应该是总的,那就是12000→2000。因为default在不用fpn是保留12000的
    post_nms_top_n = config.MODEL.RPN.POST_NMS_TOP_N_TRAIN      #2000
    if not is_train:
        pre_nms_top_n = config.MODEL.RPN.PRE_NMS_TOP_N_TEST     #1000
        post_nms_top_n = config.MODEL.RPN.POST_NMS_TOP_N_TEST   #1000(1000*6→1000)
    nms_thresh = config.MODEL.RPN.NMS_THRESH                    # 0.7
    min_size = config.MODEL.RPN.MIN_SIZE                        #0

 

# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
import torch
import torch.nn.functional as F
from torch import nn

from maskrcnn_benchmark.modeling import registry
from maskrcnn_benchmark.modeling.box_coder import BoxCoder
from maskrcnn_benchmark.modeling.rpn.retinanet.retinanet import build_retinanet
from .loss import make_rpn_loss_evaluator
from .anchor_generator import make_anchor_generator
from .inference import make_rpn_postprocessor


class RPNHeadConvRegressor(nn.Module):
    """
    A simple RPN Head for classification and bbox regression
    """

    def __init__(self, cfg, in_channels, num_anchors):
        """
        Arguments:
            cfg              : config
            in_channels (int): number of channels of the input feature
            num_anchors (int): number of anchors to be predicted
        """
        super(RPNHeadConvRegressor, self).__init__()
        self.cls_logits = nn.Conv2d(in_channels, num_anchors, kernel_size=1, stride=1)
        self.bbox_pred = nn.Conv2d(
            in_channels, num_anchors * 4, kernel_size=1, stride=1
        )

        for l in [self.cls_logits, self.bbox_pred]:
            torch.nn.init.normal_(l.weight, std=0.01)
            torch.nn.init.constant_(l.bias, 0)

    def forward(self, x):
        assert isinstance(x, (list, tuple))
        logits = [self.cls_logits(y) for y in x]
        bbox_reg = [self.bbox_pred(y) for y in x]

        return logits, bbox_reg


class RPNHeadFeatureSingleConv(nn.Module):
    """
    Adds a simple RPN Head with one conv to extract the feature
    """

    def __init__(self, cfg, in_channels):
        """
        Arguments:
            cfg              : config
            in_channels (int): number of channels of the input feature
        """
        super(RPNHeadFeatureSingleConv, self).__init__()
        self.conv = nn.Conv2d(
            in_channels, in_channels, kernel_size=3, stride=1, padding=1
        )

        for l in [self.conv]:
            torch.nn.init.normal_(l.weight, std=0.01)
            torch.nn.init.constant_(l.bias, 0)

        self.out_channels = in_channels

    def forward(self, x):
        assert isinstance(x, (list, tuple))
        x = [F.relu(self.conv(z)) for z in x]

        return x


@registry.RPN_HEADS.register("SingleConvRPNHead")
class RPNHead(nn.Module):
    """
    Adds a simple RPN Head with classification and regression heads
    """

    def __init__(self, cfg, in_channels, num_anchors):
        """
        Arguments:
            cfg              : config
            in_channels (int): number of channels of the input feature =256
            num_anchors (int): number of anchors to be predicted
        """
        super(RPNHead, self).__init__()
        self.conv = nn.Conv2d(
            in_channels, in_channels, kernel_size=3, stride=1, padding=1
        )                       #在哪里加的卷积????
        self.cls_logits = nn.Conv2d(in_channels, num_anchors, kernel_size=1, stride=1)
        self.bbox_pred = nn.Conv2d(
            in_channels, num_anchors * 4, kernel_size=1, stride=1
        )

        for l in [self.conv, self.cls_logits, self.bbox_pred]:
            torch.nn.init.normal_(l.weight, std=0.01)
            torch.nn.init.constant_(l.bias, 0)

    def forward(self, x):
        logits = []
        bbox_reg = []
        for feature in x:
            t = F.relu(self.conv(feature))
            logits.append(self.cls_logits(t))
            bbox_reg.append(self.bbox_pred(t))
        return logits, bbox_reg


class RPNModule(torch.nn.Module):
    """
    Module for RPN computation. Takes feature maps from the backbone and RPN
    proposals and losses. Works for both FPN and non-FPN.
    """

    def __init__(self, cfg, in_channels):               #in_channels=256
        super(RPNModule, self).__init__()

        self.cfg = cfg.clone()

        anchor_generator = make_anchor_generator(cfg)  #生成anchors  return anchors

        rpn_head = registry.RPN_HEADS[cfg.MODEL.RPN.RPN_HEAD]   #对谁呢???
        #@registry.RPN_HEADS.register("SingleConvRPNHead")  也属于RPN部分,多生成一层用于classification and regression。也就是P6
        #in_channels=256
        head = rpn_head(
            cfg, in_channels, anchor_generator.num_anchors_per_location()[0]
        )

        rpn_box_coder = BoxCoder(weights=(1.0, 1.0, 1.0, 1.0))

        box_selector_train = make_rpn_postprocessor(cfg, rpn_box_coder, is_train=True)
        box_selector_test = make_rpn_postprocessor(cfg, rpn_box_coder, is_train=False)

        loss_evaluator = make_rpn_loss_evaluator(cfg, rpn_box_coder)

        self.anchor_generator = anchor_generator
        self.head = head
        self.box_selector_train = box_selector_train
        self.box_selector_test = box_selector_test
        self.loss_evaluator = loss_evaluator

    def forward(self, images, features, targets=None):
        """
        Arguments:
            images (ImageList): images for which we want to compute the predictions
            features (list[Tensor]): features computed from the images that are
                used for computing the predictions(FPN得到的features变量信息,tuple类型,p2~p5,5个特征图的tensor). Each tensor in the list
                correspond to different feature levels
            targets (list[BoxList): ground-truth boxes present in the image (optional)

        Returns:
            boxes (list[BoxList]): the predicted boxes from the RPN, one BoxList per
                image.
            losses (dict[Tensor]): the losses for the model during training. During
                testing, it is an empty dict.
        """
        objectness, rpn_box_regression = self.head(features)
        anchors = self.anchor_generator(images, features)

        if self.training:
            return self._forward_train(anchors, objectness, rpn_box_regression, targets)
        else:
            return self._forward_test(anchors, objectness, rpn_box_regression)

    def _forward_train(self, anchors, objectness, rpn_box_regression, targets):
        if self.cfg.MODEL.RPN_ONLY:
            # When training an RPN-only model, the loss is determined by the
            # predicted objectness and rpn_box_regression values and there is
            # no need to transform the anchors into predicted boxes; this is an
            # optimization that avoids the unnecessary transformation.
            boxes = anchors
        else:
            # For end-to-end models, anchors must be transformed into boxes and
            # sampled into a training batch.
            with torch.no_grad():
                boxes = self.box_selector_train(
                    anchors, objectness, rpn_box_regression, targets
                )
        loss_objectness, loss_rpn_box_reg = self.loss_evaluator(
            anchors, objectness, rpn_box_regression, targets
        )
        losses = {
            "loss_objectness": loss_objectness,
            "loss_rpn_box_reg": loss_rpn_box_reg,
        }
        return boxes, losses

    def _forward_test(self, anchors, objectness, rpn_box_regression):
        boxes = self.box_selector_test(anchors, objectness, rpn_box_regression)
        if self.cfg.MODEL.RPN_ONLY:
            # For end-to-end models, the RPN proposals are an intermediate state
            # and don't bother to sort them in decreasing score order. For RPN-only
            # models, the proposals are the final output and we return them in
            # high-to-low confidence order.
            inds = [
                box.get_field("objectness").sort(descending=True)[1] for box in boxes
            ]
            boxes = [box[ind] for box, ind in zip(boxes, inds)]
        return boxes, {}


def build_rpn(cfg, in_channels):  ##256
    """
    This gives the gist of it. Not super important because it doesn't change as much
    """
    if cfg.MODEL.RETINANET_ON:
        return build_retinanet(cfg, in_channels)

    return RPNModule(cfg, in_channels)

 

在服务器中安装maskrcnn_benchmark通常遵循以下步骤: 1. **系统环境检查**: 确保服务器操作系统为Linux,maskrcnn_benchmark通常在Linux环境下开发和运行。 2. **安装依赖库**: maskrcnn_benchmark依赖于多个库,包括但不限于Python 3, PyTorch, torchvision, CMake等。可以通过以下命令安装: ```bash sudo apt-get update sudo apt-get install -y python3 python3-pip pip3 install torch torchvision sudo apt-get install -y libturbojpeg sudo apt-get install -y cmake ``` 3. **编译**: maskrcnn_benchmark可能需要编译某些依赖库(如Caffe2),根据其官方文档中的指南进行编译。 4. **安装maskrcnn_benchmark**: 你可以使用Python包管理工具pip来安装,或者直接从GitHub下载源代码后安装。 - 使用pip安装(如果可用): ```bash pip3 install maskrcnn_benchmark ``` - 从源代码安装: ```bash git clone https://github.com/facebookresearch/maskrcnn-benchmark.git cd maskrcnn-benchmark python setup.py build develop ``` 5. **配置环境变量**: 根据maskrcnn_benchmark的安装说明,可能还需要设置环境变量,比如设置`PYTHONPATH`环境变量指向maskrcnn_benchmark的安装路径。 ```bash export PYTHONPATH=/path/to/maskrcnn_benchmark:$PYTHONPATH ``` 6. **验证安装**: 安装完成后,可以通过运行maskrcnn_benchmark中的测试用例来验证安装是否成功。 ```bash python -m maskrcnn_benchmark.configs.vg_attr_config --test-only ``` 请注意,maskrcnn_benchmark可能依赖于一些特定版本的依赖库,因此在安装时需要严格按照其官方文档的指示操作,以确保所有依赖都是兼容的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值