pytorch代码实现注意力机制之SK Attention

SK注意力机制

简介:在标准卷积神经网络 (CNN) 中,每一层人工神经元的感受野被设计为共享相同的大小。在神经科学界众所周知,视觉皮层神经元的感受野大小受到刺激的调节,这在构建 CNN 时很少被考虑。我们在CNN中提出了一种动态选择机制,该机制允许每个神经元根据输入信息的多个尺度自适应地调整其感受野大小。设计了一个称为选择性内核 (SK) 单元的构建块,其中使用由这些分支中的信息引导的 softmax 注意力融合具有不同内核大小的多个分支。对这些分支的不同关注会产生不同大小的融合层神经元的有效感受野。多个 SK 单元堆叠到称为选择性内核网络 (SKNets) 的深度网络中。在ImageNet和CIFAR基准测试中,我们通过经验表明,SKNet以较低的模型复杂性优于现有的最先进的架构。详细分析表明,SKNet中的神经元可以捕获不同尺度的目标对象,这验证了神经元根据输入自适应调整其感受野大小的能力。

结构图

代码实现

import numpy as np
import torch
from torch import nn
from torch.nn import init
from collections import OrderedDict


class SKAttention(nn.Module):

    def __init__(self, channel=512, kernels=[1, 3, 5, 7], reduction=16, group=1, L=32):
        super().__init__()
        self.d = max(L, channel // reduction)
        self.convs = nn.ModuleList([])
        for k in kernels:
            self.convs.append(
                nn.Sequential(OrderedDict([
                    ('conv', nn.Conv2d(channel, channel, kernel_size=k, padding=k // 2, groups=group)),
                    ('bn', nn.BatchNorm2d(channel)),
                    ('relu', nn.ReLU())
                ]))
            )
        self.fc = nn.Linear(channel, self.d)
        self.fcs = nn.ModuleList([])
        for i in range(len(kernels)):
            self.fcs.append(nn.Linear(self.d, channel))
        self.softmax = nn.Softmax(dim=0)

    def forward(self, x):
        bs, c, _, _ = x.size()
        conv_outs = []
        ### split
        for conv in self.convs:
            conv_outs.append(conv(x))
        feats = torch.stack(conv_outs, 0)  # k,bs,channel,h,w

        ### fuse
        U = sum(conv_outs)  # bs,c,h,w

        ### reduction channel
        S = U.mean(-1).mean(-1)  # bs,c
        Z = self.fc(S)  # bs,d

        ### calculate attention weight
        weights = []
        for fc in self.fcs:
            weight = fc(Z)
            weights.append(weight.view(bs, c, 1, 1))  # bs,channel
        attention_weughts = torch.stack(weights, 0)  # k,bs,channel,1,1
        attention_weughts = self.softmax(attention_weughts)  # k,bs,channel,1,1

        ### fuse
        V = (attention_weughts * feats).sum(0)
        return V


if __name__ == '__main__':
    input = torch.randn(50, 512, 7, 7)
    se = SKAttention(channel=512, reduction=8)
    output = se(input)
    print(output.shape)
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
注意力机制深度学习中一种重要的机制,可以在不同的任务中提升模型的性能。下面是一个使用PyTorch实现的简单注意力机制的示例代码: ```python import torch import torch.nn as nn class Attention(nn.Module): def __init__(self, hidden_size): super(Attention, self).__init__() self.hidden_size = hidden_size self.attn = nn.Linear(self.hidden_size * 2, self.hidden_size) self.v = nn.Linear(self.hidden_size, 1, bias=False) def forward(self, hidden, encoder_outputs): max_len = encoder_outputs.size(0) batch_size = encoder_outputs.size(1) # 将隐藏状态复制max_len次,变成(batch_size, max_len, hidden_size)的形状 h = hidden.repeat(max_len, 1, 1).transpose(0, 1) # 将encoder_outputs和隐藏状态h拼接起来,得到(batch_size, max_len, hidden_size*2)的形状 encoder_outputs = encoder_outputs.transpose(0, 1) attn_input = torch.cat((h, encoder_outputs), dim=2) # 计算注意力分数,得到(batch_size, max_len, hidden_size)的形状 attn_scores = torch.tanh(self.attn(attn_input)) # 将注意力分数转化为(batch_size, max_len, 1)的形状 attn_weights = self.v(attn_scores).transpose(1,2) # 通过softmax函数,将注意力分数转化为(batch_size, max_len, 1)的概率分布 attn_weights = torch.softmax(attn_weights, dim=-1) # 将encoder_outputs与注意力权重相乘,得到加权后的特征向量 context = torch.bmm(attn_weights, encoder_outputs.transpose(0,1)) # 将加权后的特征向量与隐藏状态拼接起来 output = torch.cat((context, hidden), dim=2) return output, attn_weights ``` 这个代码实现了一个简单的注意力机制,用于将编码器的输出加权后与解码器的隐藏状态拼接起来。具体来说,它的输入是一个隐藏状态和编码器的输出,输出是加权后的特征向量和注意力权重。在forward方法中,它首先将隐藏状态和编码器的输出拼接起来,然后计算注意力分数,并将其转化为概率分布。接着,它将encoder_outputs与注意力权重相乘,得到加权后的特征向量。最后,它将加权后的特征向量与隐藏状态拼接起来,作为输出返回。 注意力机制是一种非常常用的机制,可以用于机器翻译、自然语言处理、语音识别等任务中,能够帮助模型更好地处理长序列输入。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我悟了-

你的激励是我肝下去的动力~

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

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

打赏作者

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

抵扣说明:

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

余额充值