OpenPose MobileNet V1 作为Backbone的模型结构(3)

OpenPose MobileNet V1 作为Backbone的模型结构(3)

Branch的合并

论文地址
论文中提到的源码地址
深度可分离卷积是如何减少计算量的
OpenPose MobileNet V1 作为Backbone的模型结构(1) MobileNet V1 的改造
OpenPose MobileNet V1 作为Backbone的模型结构(2) Initial Stage和Refinement Stage的优化
OpenPose MobileNet V1 作为Backbone的模型结构(3) Branch的合并
flyfish
在这里插入图片描述论文原文
To produce new estimation of keypoint heatmaps and pafs the refinement stage takes features from backbone concatenated with previous estimation of keypoint heatmaps and pafs. Motivated by this fact we decided to share the most of computations between heatmaps and pafs and use single prediction branch in initial and refinement stage. We share all layers except the two last, which directly produce keypoint heatmaps and pafs.

1、上图左:VGG的OpenPose有两个prediction 分支,两个branch的结构是一样的,一个用来预测keypoint heatmap,一个用来预测PAFs。
2、上图右:MobileNet的OpenPose将两个branch合并成一个,只输出阶段使用1*1的卷积分出两个branch出来。一个用来预测keypoint heatmap,一个用来预测PAFs。

Initiate stage和Refinement stage这两个Stage各自都有合并
对于卷积通常封装成各种类型的卷积
例如
conv后面是否带BatchNorm2d,是否带ReLU
conv_dw深度可分离卷积后面是否BatchNorm2d,带ReLU还是带ELU

Initiate stage的branch的合并,下面的trunk是共享的

class InitialStage(nn.Module):
    def __init__(self, num_channels, num_heatmaps, num_pafs):
        super().__init__()
        self.trunk = nn.Sequential(
            conv(num_channels, num_channels, bn=False),
            conv(num_channels, num_channels, bn=False),
            conv(num_channels, num_channels, bn=False)
        )
        self.heatmaps = nn.Sequential(
            conv(num_channels, 512, kernel_size=1, padding=0, bn=False),
            conv(512, num_heatmaps, kernel_size=1, padding=0, bn=False, relu=False)
        )
        self.pafs = nn.Sequential(
            conv(num_channels, 512, kernel_size=1, padding=0, bn=False),
            conv(512, num_pafs, kernel_size=1, padding=0, bn=False, relu=False)
        )

    def forward(self, x):
        trunk_features = self.trunk(x)
        heatmaps = self.heatmaps(trunk_features)
        pafs = self.pafs(trunk_features)
        return [heatmaps, pafs]

Refinement stage的branch的合并,下面的trunk是共享的

对于Refinement stage先有Refinement stage block,多个这样的block组成Refinement stage

class RefinementStageBlock(nn.Module):
    def __init__(self, in_channels, out_channels):
        super().__init__()
        self.initial = conv(in_channels, out_channels, kernel_size=1, padding=0, bn=False)
        self.trunk = nn.Sequential(
            conv(out_channels, out_channels),
            conv(out_channels, out_channels, dilation=2, padding=2)
        )

    def forward(self, x):
        initial_features = self.initial(x)
        trunk_features = self.trunk(initial_features)
        return initial_features + trunk_features


class RefinementStage(nn.Module):
    def __init__(self, in_channels, out_channels, num_heatmaps, num_pafs):
        super().__init__()
        self.trunk = nn.Sequential(
            RefinementStageBlock(in_channels, out_channels),
            RefinementStageBlock(out_channels, out_channels),
            RefinementStageBlock(out_channels, out_channels),
            RefinementStageBlock(out_channels, out_channels),
            RefinementStageBlock(out_channels, out_channels)
        )
        self.heatmaps = nn.Sequential(
            conv(out_channels, out_channels, kernel_size=1, padding=0, bn=False),
            conv(out_channels, num_heatmaps, kernel_size=1, padding=0, bn=False, relu=False)
        )
        self.pafs = nn.Sequential(
            conv(out_channels, out_channels, kernel_size=1, padding=0, bn=False),
            conv(out_channels, num_pafs, kernel_size=1, padding=0, bn=False, relu=False)
        )

    def forward(self, x):
        trunk_features = self.trunk(x)
        heatmaps = self.heatmaps(trunk_features)
        pafs = self.pafs(trunk_features)
        return [heatmaps, pafs]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西笑生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值