SE注意力机制

简介

SENet是2017年ImageNet比赛的冠军,2018年CVPR引用量第一。论文链接:SENet

意义

较早的将attention引入到CNN中,模块化化设计。

目的:

SE模块的目的是想通过一个权重矩阵,从通道域的角度赋予图像不同位置不同的权重,得到更重要的特征信息。

主要操作

SE模块的主要操作:挤压(Squeeze)、激励(Excitation)

算法流程图

在这里插入图片描述
通过一系列操作得到一个 1 ∗ 1 ∗ C 1*1*C 11C的权重矩阵,对原特征进行重构(不同颜色表示不同的数值,用来衡量通道的重要性)

过程

第一步、

Transformation ( F t r ) (F{_t}{_r}) (Ftr):给定一个input特征图 X X X,让其经过 F t r F{_t}{_r} Ftr操作生成特征图 U U U
注意:在常用的卷积神经网络中Transformation操作一般为一个卷积操作。我们通常在聊SE注意力时通常不包含这一步。

第二步、

Squeeze ( F s q ( ⋅ ) ) (F{_s}{_q}(·)) (Fsq())::这一步将特征图进行全局平均池化,生成一个 1 ∗ 1 ∗ C 1*1*C 11C的向量,这样每个通道让一个数值表示。
注释:对 U U U实现全局低维嵌入,相当于一个数值拥有该通道的全局感受野。
公式:在这里插入图片描述

此外:论文中给出了使用平均池化与最大池化的实验对比。
在这里插入图片描述

第三步、

Excitation ( F e x ) (F{_e}{_x}) (Fex):这一步通过两层全连接层完成,通过权重W生成我们我所要的权重信息,其中W是通过学习得到的,用来显示的建模我们我需要的特征相关性。
在这里插入图片描述
通过两个全连接层 W 1 W{_1} W1 , W 2 W{_2} W2对上一步得到的向量 z z z进行处理,得到我们想要的通道权重值 s s s,经过两层全连接层后,s中不同的数值表示不同通道的权重信息,赋予通道不同的权重。
注意:两层全连接层之间存在一个超参数 R R R, 向量 z z z ( 1 ∗ 1 ∗ C ) (1*1*C) (11C)经过第一层全连接层后维度由
( 1 ∗ 1 ∗ C ) (1*1*C) (11C)变为 ( 1 ∗ 1 ∗ C / R ) (1*1*C/R) (11C/R),再经过第二层全连接层为度由 ( 1 ∗ 1 ∗ C / R ) (1*1*C/R) (11C/R)变为 ( 1 ∗ 1 ∗ C ) (1*1*C) (11C)。第一层全连接层的激活函数为ReLU,第二层全连接层的激活函数为Sigmoid。

第四步、

Scale ( F s c a l e ) (F{_{scale}}) (Fscale):由算法流程图可以看出,第四步的操作是将第三步生成权重向量 s s s对特征图 U U U进行权重赋值,得到我们想要的特征图 X ~ \tilde X X~,其尺寸大小与特征图 U U U完全一样,SE模块不改变特征图的小大。
在这里插入图片描述
通过生成的特征向量 s s s 1 ∗ 1 ∗ C 1*1*C 11C)与特征图 U U U( H ∗ W ∗ C H*W*C HWC),对应通道相乘,即特征图 U U U中每个通道的 H ∗ W H*W HW个数值都乘 s s s中对应通道的权值。

SE模块的结构图

在这里插入图片描述
SE模块是一个即插即用的模块,在上图中左边是在一个卷积模块之后直接插入SE模块,右边是在ResNet结构中添加了SE模块。

实现代码

import torch.nn as nn

class SEModel(nn.Module):
    def __init__(self, channel, reduction=16):
        super(SEModel, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(channel, channel // reduction, bias=False),
            nn.ReLU(),
            nn.Linear(channel // reduction, channel, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y.expand_as(x)

网上有较多的公开代码,都可以进行参考。

最后

SE模块在使用时如何选择添加的位置是值得考虑的问题,如何实现最大化的提升。
MobileNetV3中使用了SE模块,通过神经网络架构搜索进行了最优位置选择,值得思考与学习。

如有错误,望大家指正。B站上有很多大佬的讲解视频,喜欢视频讲解的可以看一下。

### SE注意力机制工作原理 SENet(Squeeze-and-Excitation Network)是一种用于增强卷积神经网络性能的技术。通过引入通道间的依赖关系,该模型能够更有效地捕捉特征的重要性。 #### Squeeze操作 在网络的每一层中,SE模块首先执行squeeze操作来获取全局信息。具体来说,对于给定的一个特征图 \( F \),其尺寸为 \( H×W×C \),其中\( C \)表示通道数,squeeze过程会将每个通道的空间维度压缩成单个数值,形成一个长度为\( C \)的一维向量。这一步骤可以通过全局平均池化实现[^1]: \[ z_c=\frac{1}{HW}\sum_{i=1}^{H}\sum_{j=1}^{W}F(i,j,c),\quad c∈[0,C−1] \] #### Excitation操作 接着,在excitation阶段,上述得到的一维向量被送入两个全连接层组成的瓶颈结构中处理。第一个全连接层负责降维至较小规模;第二个则恢复到原始大小并应用sigmoid激活函数生成权重系数。这些系数反映了各个通道的重要程度[^2]: ```python import torch.nn as nn class SELayer(nn.Module): def __init__(self, channel, reduction=16): super(SELayer, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Sequential( nn.Linear(channel, channel // reduction), nn.ReLU(inplace=True), nn.Linear(channel // reduction, channel), nn.Sigmoid() ) def forward(self, x): b, c, _, _ = x.size() y = self.avg_pool(x).view(b, c) y = self.fc(y).view(b, c, 1, 1) return x * y.expand_as(x) ``` 最后,计算出的权重会被重新应用于对应的输入特征上,从而调整各通道贡献度,使得重要的部分得以突出显示而抑制不那么有用的信息。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

renxingshen2022

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

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

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

打赏作者

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

抵扣说明:

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

余额充值