深度学习| Attention U-Net(包含Attention Gate代码)

前言:最近在阅读一篇文章,用到了Attention Unet所以特地写了两篇文章,上一篇文章介绍了Attention的基础知识,这篇文化在哪个介绍Attention Unet相关知识以及代码。

基础

注意力机制

Attention介绍:就是模仿人的注意力机制设计,人看到一个东西,会把注意力放在需要关注的地方,把其它无关的信息过滤掉。下面的图是人类看到图片注意力热力图。
在这里插入图片描述

软注意力和硬注意力

软注意力(Soft Attention):加权图像的每个像素。 高相关性区域乘以较大的权重,而低相关性区域标记为较小的权重。

硬注意力(Hard Attention):一次选择一个图像的一个区域作为注意力,设成1,其他设为0。

通常采用的都是软注意力,因为软注意力能参与反向传播,而硬注意力机制不行,得借助强化学习的手段训练。而且软注意力机制模块大多数都不会改变输出尺寸,从而可以很灵活的插入到卷积网络的各个部分。

U-Net为什么需要Attention

既然Attention U-Net是U-Net的改进,那么需要先简单回顾一下U-Net,来更好对比。

下面是U-Net的网络结构图

在这里插入图片描述

从U-Net的结构图中看出,为了避免在Decoder解码器时丢失大量的细节,使用了Skip Connection跳跃链接,将Encoder编码器中提取的信息直接连接到Decoder对应的层上。

但是,Encoder提取的low-level feature有很多的冗余信息,也就是提取的特征不太好,可能对后面并没有帮助,这就是U-Net网络存在的问题

该问题可以通过在U-Net上加入注意力机制,来减少冗余的Skip Connection。

Attention U-Net

Attention U-Net发布比Res U-Net要早些,主要应用在医学图像分割领域。

Attention U-Net:在U-Net基础上,通过在U-Net上加入软注意力机制,来减少冗余的Skip Connection。

加入软注意机制随让能够减少冗余,但会增加训练参数,从而导致计算成本有所提高。所以集成到标准U-Net网络中时要简单方便、计算开销小。

Attention U-Net结构图
在这里插入图片描述
对基础U-Net网络结构,可以发现在跳跃链接中都加入了Attention Gate模块。而原始U-Net只是单纯的把同层的下采样层的特征直接连接到上采样层中。

Attention Gate模块结构图
在这里插入图片描述
x l x^l xl是当前层Encoder下采样跳跃链接来的数据;g是来自Decoder下一层的数据,所以g的尺寸大小是 x l x^l xl的二分之一。所以要对 x l x^l xl下采样或者g上采样,来确保尺寸一致,从而得到 W g W_g Wg W x W_x Wx。尺寸一致后, W g W_g Wg W x W_x Wx进行逐点“+”操作,然后经过relu,再1×1卷积和sigmoid函数从而得到注意力系数,最后再结果一个resample把尺寸还原回来。还原后的注意力系数就可以和特征图 x l x^l xl进行加权。

为什么需要relu和sigmoid激活函数,因为 W g W_g Wg W x W_x Wx进行“+”操作后还是线性操作,激活函数可以引入非线性,从而更好拟合。

简单点来说,g是decoder的数据,对比同层的 x l x^l xl要学到的东西更多,信息更加准确。g就是Attention机制中的Q(Query),告诉了模型需要要从 x l x^l xl中学习的重点。

Attention Gate模块代码

class Attention_block(nn.Module):
    def __init__(self, F_g, F_l, F_int):
        super(Attention_block, self).__init__()
        self.W_g = nn.Sequential(
            nn.Conv2d(F_g, F_int, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(F_int)
        )

        self.W_x = nn.Sequential(
            nn.Conv2d(F_l, F_int, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(F_int)
        )

        self.psi = nn.Sequential(
            nn.Conv2d(F_int, 1, kernel_size=1, stride=1, padding=0, bias=False),
            nn.BatchNorm2d(1),
            nn.Sigmoid()
        )

        self.relu = nn.ReLU(inplace=True)

    def forward(self, g, x):
        # 下采样的gating signal 卷积
        g1 = self.W_g(g)
        # 上采样的 l 卷积
        x1 = self.W_x(x)
        # concat + relu
        psi = self.relu(g1 + x1)
        # channel 减为1,并Sigmoid,得到权重矩阵
        psi = self.psi(psi)
        # 返回加权的 x
        return x * psi
### Attention UNet 模型架构 Attention UNet 是一种改进版的U-Net网络,通过引入注意力机制来提升医学图像分割的效果。该模型的核心在于其能够动态调整不同区域的重要性,从而更好地聚焦于目标器官并抑制背景噪声。 #### 基础UNet结构 基础UNet由编码器和解码器两部分组成。编码器负责提取输入图像特征,通常采用卷积层与池化操作交替的方式逐步降低空间分辨率;而解码器则用于恢复原始尺寸,主要依赖转置卷积(反卷积)以及跳跃连接将高层次语义信息传递回低层次位置[^1]。 #### 注意力模块设计 为了进一步优化这一过程,在每个跳跃连接处加入了一个特殊的门控单元——即所谓的“attention gate”。此gate会计算来自浅层特征图与深层特征图之间的相似度得分,并据此生成一个加权掩模应用于即将融合的数据流之上。具体来说: - **门控信号**:取自下采样路径末端较深的位置; - **输入信号**:对应同一水平线上的上采样分支起点; - **激活函数**:一般选用sigmoid以确保输出范围位于0到1之间。 这种做法使得网络可以在训练期间自动习得哪些部位应当受到更多关注,进而改善最终预测质量[^2]。 ```python class AttentionBlock(nn.Module): """定义单个注意力块""" def __init__(self, F_g, F_l, n_coefficients): super().__init__() self.W_gate = nn.Sequential( nn.Conv2d(F_g, n_coefficients, kernel_size=1), nn.BatchNorm2d(n_coefficients) ) self.W_input = nn.Sequential( nn.Conv2d(F_l, n_coefficients, kernel_size=1), nn.BatchNorm2d(n_coefficients) ) self.psi = nn.Sequential( nn.ReLU(inplace=True), nn.Conv2d(n_coefficients, 1, kernel_size=1), nn.Sigmoid() ) def forward(self, g, x): gated_signal = self.W_gate(g) input_signal = self.W_input(x) combined_signals = gated_signal + input_signal attention_mask = self.psi(combined_signals) return x * attention_mask ``` 上述代码片段展示了如何构建一个简单的二维注意力模块。这里`F_g`, `F_l`分别代表门控信号通道数和输入信号通道数,而`n_coefficients`则是中间处理阶段使用的特征数量。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值