maskrcnn_benchmark理解记录——modeling\roi_heads\keypoint_head\roi_keypoint_feature_extractors.py

 这里是keypoints Head特征提取部分。p2~p5 做keypoint head的特征提取部分,并构建了后面的层。

也就是ROIAlign→14*14*256→14*14*512→*8→14*14*512这部分

先对不同P2~P5特征图(list[Tensor])的proposals(list[BoxList])进行ROIAlign。生成5个 14*14*256的ROI特征图。接着对五个ROI特征图(list[Tensor]),逐步进行*8的卷积+relu。(5个特征图是以list形式放一起的,写在一起往后处理)

注意:没有7*7*17和后面回归的部分

'''# 整体思路:先为网络定义一个Darknet类,然后里面肯定有init,foward函数,
# 这里还有load_weight函数,在init初始化的时候,需要将利用cfg构建一个网络框架。具体关系在forward函数中'''
#todo 1. 转换输入:根据cfg文件,先把每个block单独存储(作为字典),放到blocks(列表)当中。
#一 、 在init的时候,需要利用cfg构建网络框架。需要创建两个函数parse_cfg(cfgfile) 和 create_modules(self.blocks)

#todo 2.根据blocks中的block字典信息可以创建module(nn.Sequential() #不断创造新的module),放到module_list(nn.moduleList)当中。
#二 、 再定义forward函数: def forward(self, x, CUDA):

from torch import nn
from torch.nn import functional as F

from maskrcnn_benchmark.modeling import registry
from maskrcnn_benchmark.modeling.poolers import Pooler

from maskrcnn_benchmark.layers import Conv2d


@registry.ROI_KEYPOINT_FEATURE_EXTRACTORS.register("KeypointRCNNFeatureExtractor")
class KeypointRCNNFeatureExtractor(nn.Module):
    def __init__(self, cfg, in_channels):                            ##in_channels=256
        super(KeypointRCNNFeatureExtractor, self).__init__()
        #14  那就是keypoint head部分是14*14
        resolution = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_RESOLUTION
        # (0.25, 0.125, 0.0625, 0.03125) 那就是说是p2~p5 做keypoint head部分
        scales = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_SCALES
        # 2
        sampling_ratio = cfg.MODEL.ROI_KEYPOINT_HEAD.POOLER_SAMPLING_RATIO
        out_channels = 10
        c_out = resolution *resolution *out_channels   #7*7*10
        #self.global_context_module = GlobalContextModule(in_channels, 256, self.c_out, 15)
        # ROIAlign
        pooler = Pooler(
            output_size=(resolution, resolution),                  #14 *14
            scales=scales,                                         # (0.25, 0.125, 0.0625, 0.03125)
            sampling_ratio=sampling_ratio,
        )
        self.pooler = pooler

        input_features = in_channels                                 ##in_channels=256
        layers = cfg.MODEL.ROI_KEYPOINT_HEAD.CONV_LAYERS             #tuple(512 for _ in range(8))
        #(512, 512, 512, 512, 512, 512, 512, 512)       (range(8):0~7)
        next_feature = input_features
        self.blocks = []
        for layer_idx, layer_features in enumerate(layers, 1):
            ''' 1 512    ... → ...  8 512'''
            layer_name = "conv_fcn{}".format(layer_idx)
            # todo  1.定义卷积层
            module = Conv2d(next_feature, layer_features, 3, stride=1, padding=1)
            '''torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)'''
            # todo  2.初始化卷积层参数 weight kaiming_normal_正态分布  std=sqrt((3/((1+a**a)*fan_in))
            nn.init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
            #针对于Relu的激活函数,基本使用kaiming 初始化卷积层参数的,还有kaiming_uniform_均匀分布 mode='fan_in',  bound=sqrt((6/((1+a**a)*fan_in
            #a:该层后面一层的激活函数中负的斜率(默认为ReLU,此时a=0) mode:‘fan_in’ (default) 或者 ‘fan_out’.
            # 使用fan_in保持weights的方差在前向传播中不变;使用fan_out保持weights的方差在反向传播中不变
            # todo  3.初始化卷积层参数 bias  为 0
            nn.init.constant_(module.bias, 0)  #初始化为常数torch.nn.init.constant_(tensor, val)初始化整个矩阵为常数val
            # todo  4.添加卷积层名称和信息 #列表存储所有module
            self.add_module(layer_name, module)
            '''将子模块添加到当前模块。可以使用给定名称将模块作为属性进行访问。
        ARGS:
             name(字符串):子模块的名称。 可以使用给定名称参数(Module):要添加到模块的子模块,从该模块访问子模块。'''
            # todo  5.更改卷积层输出channels
            next_feature = layer_features
            self.blocks.append(layer_name)
        self.out_channels = layer_features

    def forward(self, x, proposals):
        '''Pooler()(x, proposals)
        参数Arguments:
            x (list[Tensor]): feature maps for each level
            boxes (list[BoxList]): boxes to be used to perform the pooling operation.
            因为是ROIAlign 也就是对proposals池化咯
        Returns:
            result (Tensor)'''
        #h = self.global_context_module(x)
        x = self.pooler(x, proposals)
        for layer_name in self.blocks:
            x = F.relu(getattr(self, layer_name)(x))  #TODO 这里应该是对五个特征图的list,逐步进行*8的卷积+relu
        return x


def make_roi_keypoint_feature_extractor(cfg, in_channels):
    func = registry.ROI_KEYPOINT_FEATURE_EXTRACTORS[
        cfg.MODEL.ROI_KEYPOINT_HEAD.FEATURE_EXTRACTOR
    ]           #@registry.ROI_KEYPOINT_FEATURE_EXTRACTORS.register("KeypointRCNNFeatureExtractor")
    return func(cfg, in_channels)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值