绿色 网站 源码今日热点新闻事件及评论
论文《Selective Kernel Networks》
1、作用
该论文介绍了选择性核网络(SKNets),这是一种在卷积神经网络(CNN)中的动态选择机制,允许每个神经元根据输入自适应地调整其感受野大小。这种方法受到视觉皮层神经元对不同刺激响应时感受野大小变化的启发,在CNN设计中不常利用此特性。
2、机制
SKNets利用了一个称为选择性核(SK)单元的构建模块,该模块包含具有不同核大小的多个分支。这些分支通过一个softmax注意力机制融合,由这些分支中的信息引导。这个融合过程使得神经元能够根据输入自适应地调整其有效感受野大小。
3、独特优势
1、自适应感受野:
SKNets中的神经元可以基于输入动态调整其感受野大小,模仿生物神经元的适应能力。这允许在不同尺度上更有效地处理视觉信息。
2、计算效率:
尽管为了适应性而纳入了多种核大小,SKNets仍然保持了较低的模型复杂度,与现有最先进的架构相比。通过仔细的设计选择,如使用高效的分组/深度卷积和注意力机制中的缩减比率来控制参数数量,实现了这种效率。
3、性能提升:
在ImageNet和CIFAR等基准测试上的实验结果显示,SKNets在具有相似或更低模型复杂度的情况下,超过了其他最先进的架构。适应性调整感受野的能力可能有助于更有效地捕捉不同尺度的目标对象,提高识别性能。
4、代码
import numpy as np
import torch
from torch import nn
from torch.nn import init
from collections import OrderedDictclass 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))# 注意力权重的Softmax层self.softmax = nn.Softmax(dim=0)def forward(self, x):bs, c, _, _ = x.size()conv_outs = []# 通过不同尺寸的卷积核处理输入for conv in self.convs:conv_outs.append(conv(x))feats = torch.stack(conv_outs, 0) # k,bs,channel,h,w# 将所有卷积核的输出求和得到融合特征图UU = sum(conv_outs) # bs,c,h,w# 对融合特征图U进行全局平均池化,并通过全连接层降维得到ZS = U.mean(-1).mean(-1) # bs,cZ = self.fc(S) # bs,d# 计算每个卷积核对应的注意力权重weights = []for fc in self.fcs:weight = fc(Z)weights.append(weight.view(bs, c, 1, 1)) # bs,channelattention_weights = torch.stack(weights, 0) # k,bs,channel,1,1attention_weights = self.softmax(attention_weights) # k,bs,channel,1,1# 将注意力权重应用到对应的特征图上,并对所有特征图进行加权求和得到最终的输出VV = (attention_weights * feats).sum(0)return V# 示例用法
if __name__ == '__main__':input = torch.randn(50, 512, 7, 7)sk = SKAttention(channel=512, reduction=8)output = sk(input)print(output.shape) # 输出经过SK注意力处理后的特征图形状