前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于Pytorch的动态卷积复现

基于Pytorch的动态卷积复现

作者头像
BBuf
发布2020-09-10 16:25:56
3.2K0
发布2020-09-10 16:25:56
举报
文章被收录于专栏:GiantPandaCVGiantPandaCV

【GaintPandaCV导语】 最近动态卷积开始有人进行了研究,也有不少的论文发表(动态卷积论文合集https://github.com/kaijieshi7/awesome-dynamic-convolution),但是动态卷积具体的实现代码却很少有文章给出。本文以微软发表在CVPR2020上面的文章为例,详细的讲解了动态卷积实现的难点以及如何动分组卷积巧妙的解决。希望能给大家以启发。

这篇文章也同步到知乎平台,链接为:https://zhuanlan.zhihu.com/p/208519425

论文的题目为《Dynamic Convolution: Attention over Convolution Kernels》

paper的地址arxiv.org/pdf/1912.0345

简单回顾

这篇文章主要是改进传统卷积,让每层的卷积参数在推理的时候也是随着输入可变的,而不是传统卷积中对任何输入都是固定不变的参数。(由于本文主要说明的是代码如何实现,所以推荐给大家一个讲解论文的连接:Happy:动态滤波器卷积|DynamicConv)

代码语言:javascript
复制
class attention2d(nn.Module):
    def __init__(self, in_planes, K,):
        super(attention2d, self).__init__()
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        self.fc1 = nn.Conv2d(in_planes, K, 1,)
        self.fc2 = nn.Conv2d(K, K, 1,)

    def forward(self, x):
        x = self.avgpool(x)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x).view(x.size(0), -1)
        return F.softmax(x, 1)

具体代码如下:

代码语言:javascript
复制
class Dynamic_conv2d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, K=4,):
        super(Dynamic_conv2d, self).__init__()
        assert in_planes%groups==0
        self.in_planes = in_planes
        self.out_planes = out_planes
        self.kernel_size = kernel_size
        self.stride = stride
        self.padding = padding
        self.dilation = dilation
        self.groups = groups
        self.bias = bias
        self.K = K
        self.attention = attention2d(in_planes, K, )

        self.weight = nn.Parameter(torch.Tensor(K, out_planes, in_planes//groups, kernel_size, kernel_size), requires_grad=True)
        if bias:
            self.bias = nn.Parameter(torch.Tensor(K, out_planes))
        else:
            self.bias = None


    def forward(self, x):#将batch视作维度变量,进行组卷积,因为组卷积的权重是不同的,动态卷积的权重也是不同的
        softmax_attention = self.attention(x)
        batch_size, in_planes, height, width = x.size()
        x = x.view(1, -1, height, width)# 变化成一个维度进行组卷积
        weight = self.weight.view(self.K, -1)

        # 动态卷积的权重的生成, 生成的是batch_size个卷积参数(每个参数不同)
        aggregate_weight = torch.mm(softmax_attention, weight).view(-1, self.in_planes, self.kernel_size, self.kernel_size)
        if self.bias is not None:
            aggregate_bias = torch.mm(softmax_attention, self.bias).view(-1)
            output = F.conv2d(x, weight=aggregate_weight, bias=aggregate_bias, stride=self.stride, padding=self.padding,
                              dilation=self.dilation, groups=self.groups*batch_size)
        else:
            output = F.conv2d(x, weight=aggregate_weight, bias=None, stride=self.stride, padding=self.padding,
                              dilation=self.dilation, groups=self.groups * batch_size)

        output = output.view(batch_size, self.out_planes, output.size(-2), output.size(-1))
        return output

完整的代码在github.com/kaijieshi7/D,大家觉得有帮助的话,求点个星星。

纸上得来终觉浅,绝知此事要躬行。试下代码,方能体会其中妙处。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GiantPandaCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简单回顾
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档