当前位置:首页> AI教程> Dynamic Convolution: Attention over Convolution Kernels

Dynamic Convolution: Attention over Convolution Kernels

释放双眼,带上耳机,听听看~!
本文介绍了一种新型的卷积神经网络操作 - 动态卷积,通过引入注意力机制来动态调整卷积核的采样点,更好地适应输入数据的空间结构。

关键词:CVPR 、 动态卷积 、 涨点

论文:1912.03458.pdf (arxiv.org)

前言

  在这里我们将回顾一下2020年的顶刊论文 《Dynamic Convolution: Attention over Convolution Kernels》 在本文里将详细介绍一种新型的卷积神经网络操作,即动态卷积(Dynamic Convolution)。动态卷积是一种基于注意力机制的卷积操作,它可以自适应地调整卷积核的采样点,从而更好地适应输入数据的空间结构。本文将首先介绍传统的卷积操作的缺点,然后详细介绍动态卷积的原理和实现方式。

传统卷积的缺点

  传统的卷积运算使用一个固定的内核来扫描输入数据。然而,这个固定的核可能并不总是与输入的空间结构很好地对齐。传统卷积结构相对于动态卷积存在以下缺点:

  1. 固定采样点:传统卷积结构使用固定的采样点来对输入进行卷积操作,这种方式可能无法适应输入数据的空间结构变化,导致模型无法充分提取特征。
  2. 固定核大小:传统卷积结构使用固定的核大小来卷积输入数据,这种方式可能无法适应不同空间位置的特征差异,从而影响模型性能。
  3. 计算量大:传统卷积结构的计算量较大,尤其是在高维数据上时,需要消耗大量的计算资源,导致模型的训练和推理速度较慢。
  4. 特征冗余:传统卷积结构使用相同的核对整个特征图进行卷积操作,这种方式可能会产生特征冗余,导致模型无法充分利用输入数据的特征。
  5. 空间不变性:传统卷积结构具有空间不变性,即无论输入数据中的特征在图像中的位置如何,卷积核始终可以从输入中提取出相同的特征,这可能会导致模型忽略一些空间信息,从而影响模型的性能。

  针对传统卷积的缺点,我们提出了一种动态卷积:动态卷积通过引入一组额外的可学习参数来解决这个问题,称为偏移量,允许内核根据输入动态调整。动态卷积通过引入可学习的偏移量来解决传统卷积结构的缺点,从而提高模型的性能。

动态卷积

  动态卷积不是每层使用一个卷积核,而是根据它们的注意力(依赖于输入)动态聚合多个并行卷积核。装配多个ker不仅由于内核尺寸小而计算效率高,而且由于这些内核通过注意以非线性方式聚合,因此具有更强的表示能力。

原理

  动态卷积的核心思想是通过引入可学习的偏移量来调整卷积核的采样点,从而更好地适应输入数据的空间结构。具体来说,动态卷积首先在输入特征图上应用一个类似于注意力机制的模块,该模块通过学习输入特征图中每个空间位置的重要性来调整卷积核的采样点。然后,动态卷积使用调整后的卷积核对输入数据进行卷积操作。
Dynamic Convolution: Attention over Convolution Kernels

实现

动态卷积的实现方式包括以下步骤:

(1) 定义偏移量:定义一个偏移量矩阵M∈RH×W×K2M in mathbb{R}^{H times W times K^2},其中HHWW分别表示输入特征图的高度和宽度,KK表示卷积核的大小。偏移量矩阵MM的每个元素表示对应空间位置上卷积核中心点的偏移量。

(2) 计算卷积核采样点:使用偏移量矩阵MM计算每个空间位置上卷积核的采样点,即将卷积核中心点的坐标(i,j)(i,j)加上对应空间位置上的偏移量,得到新的采样点坐标(i′,j′)(i’,j’)

(3) 应用卷积核:使用新的采样点坐标(i′,j′)(i’,j’)在输入特征图上应用卷积核,得到输出特征图。

(4) 训练模型:训练模型时,需要将偏移量矩阵MM作为可训练参数加入模型中,并使用反向传播算法来更新偏移量矩阵MM,从而使得模型能够自适应地调整卷积核的采样点,更好地适应输入数据的空间结构。

Dynamic Convolution: Attention over Convolution Kernels

代码实现:

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

class attention2d(nn.Module):
    def __init__(self, in_planes, ratios, K, temperature, init_weight=True):
        super(attention2d, self).__init__()
        assert temperature%3==1
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        if in_planes!=3:
            hidden_planes = int(in_planes*ratios)+1
        else:
            hidden_planes = K
        self.fc1 = nn.Conv2d(in_planes, hidden_planes, 1, bias=False)
        # self.bn = nn.BatchNorm2d(hidden_planes)
        self.fc2 = nn.Conv2d(hidden_planes, K, 1, bias=True)
        self.temperature = temperature
        if init_weight:
            self._initialize_weights()


    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            if isinstance(m ,nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def updata_temperature(self):
        if self.temperature!=1:
            self.temperature -=3
            print('Change temperature to:', str(self.temperature))


    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/self.temperature, 1)

class DYConv2d(nn.Module):
    def __init__(self, in_planes, out_planes, kernel_size, ratio=0.25, stride=1, padding=0, dilation=1, groups=1, bias=True, K=4,temperature=34, init_weight=True):
        super(DYConv2d, 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, ratio, K, temperature)

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

        #TODO 初始化
    def _initialize_weights(self):
        for i in range(self.K):
            nn.init.kaiming_uniform_(self.weight[i])


    def update_temperature(self):
        self.attention.updata_temperature()

    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(batch_size*self.out_planes, self.in_planes//self.groups, 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


if __name__ == '__main__':
    x = torch.randn(1, 3, 256, 256)
    model = DYConv2d(in_planes=3, out_planes=16, kernel_size=3, ratio=0.25, padding=1,)
    print(model(x).shape)

吐槽

  在网上看见有好多人吐槽这篇文章够水,尤其是吐槽这篇文章是仿照SENet写的,网友给出的论证如下:
将se的sigmoid改成sofmax,把原来se用在feature map上的attention用在卷积核上 。就这样法了一篇顶刊文章,属实水到家了。

  当然也有人感觉和Google的 cond conv区别不大,也有人感觉这篇文章【撞衫】 SK Conv,这个也是自适应卷积,融合多尺度,CVPR2019的文章。

*本文正在参加 人工智能创作者扶持计划 ” *

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

矩阵的初等变换及逆矩阵求法

2023-12-14 13:38:14

AI教程

Jina: 跨模态搜索与向量检索技术

2023-12-14 13:48:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索