【每天一篇深度学习论文】(CVPR2024)即插即用高效上采样卷积块EUCB

论文介绍

题目

EMCAD:Efficient Multi-scale Convolutional Attention Decoding for Medical Image Segmentation

论文地址

https://arxiv.org/pdf/2405.06880

创新点

  • 多尺度卷积解码器:提出了一种高效的多尺度卷积注意力解码器(EMCAD),专门设计用于医学图像分割任务,通过多尺度深度卷积块增强特征表示,有助于在有限的计算资源下提高分割性能。
  • 多尺度卷积注意力模块:引入MSCAM模块,通过多尺度的深度卷积抑制无关区域并增强特征图,从而捕捉多尺度显著特征,降低了计算成本。
  • 大核分组注意力门:在解码器中加入了一种大核分组注意力门,通过更大局部上下文捕捉显著特征,提升了模型对重要区域的关注度。
  • 更低的计算成本与参数量:与现有的最先进方法相比,EMCAD在保持或提升分割精度的同时,显著减少了模型参数和浮点运算次数(FLOPs),在多个医学图像分割基准上达到了最优性能。
  • 广泛适配性:EMCAD可用于不同的编码器结构,在多个医学图像分割任务中表现出优越的性能和适应性,适合在计算资源受限的实际应用场景中应用。

方法

整体结构

该模型由一个分层编码器和高效多尺度卷积注意力解码器(EMCAD)组成,通过编码器提取不同尺度的特征图,然后利用EMCAD中的多尺度卷积注意力模块、分组注意力门和上采样模块逐步融合和增强这些特征,实现精确的医学图像分割。最终,通过分割头输出高分辨率的分割结果,模型在保持高精度的同时显著降低了计算成本。
在这里插入图片描述

  • 分层编码器:模型使用了层次化的编码器来提取不同尺度的特征图,这些特征图被分为多个阶段。编码器可以是PVTv2-B0或PVTv2-B2等预训练模型,用于捕捉输入图像的多尺度信息。分层编码器输出四个特征图(即X1, X2, X3, X4),用于后续解码处理。
  • EMCAD解码器:这是论文的核心创新部分,包含多个模块:
    • 多尺度卷积注意力模块(MSCAM):通过深度卷积在不同尺度上对特征图进行处理,增强特征表示并抑制无关区域。
    • 核分组注意力门(LGAG):通过分组卷积结合大核,进一步融合编码器和解码器之间的特征,以捕捉更大的上下文信息。
    • 高效上采样卷积块(EUCB):该模块用于逐步上采样特征图,将特征的空间分辨率提升到目标输出的分辨率。
    • 分割头(SH):每个阶段的特征图都通过一个1×1卷积输出一个分割图,最终整合多个分割图生成最终的分割结果。
    • 多阶段损失和输出整合:解码器每个阶段生成的分割图会参与损失计算,采用多种组合方式计算损失,以强化各阶段输出的精度。最终分割图使用Sigmoid或Softmax函数生成二分类或多分类的分割结果。

即插即用模块作用

EUCB 作为一个即插即用模块,主要适用于

  • 医学图像分割:如CT、MRI等医学影像的像素级分割任务。
  • 语义分割:广泛应用于需要精细分割的任务中,包括遥感图像分析、自动驾驶中的路面分割等。
  • 资源受限场景:在计算资源有限的设备(如边缘设备、移动端)上实现高效图像分割。

消融实验结果

在这里插入图片描述

  • 展示了不同组件对模型性能的影响,评估了解码器的级联结构、大核分组注意力门(LGAG)和多尺度卷积注意力模块(MSCAM)的贡献。实验结果显示,逐步添加这些模块能显著提升模型的DICE分数,其中MSCAM的效果尤为显著,当同时使用LGAG和MSCAM时,模型达到了最佳性能。这表明这两个模块在捕捉多尺度特征和增强局部上下文信息方面发挥了关键作用。

在这里插入图片描述

  • 探讨了多尺度卷积内不同卷积核的选择对性能的影响。实验结果表明,使用1x1、3x3和5x5卷积核组合能够带来最佳性能,这一组合在捕捉多尺度特征方面具有优势。而进一步添加更大的卷积核(如7x7或9x9)反而降低了性能,说明适当的卷积核大小组合有助于模型在保持计算效率的同时提升分割效果。

即插即用模块

import torch.nn as nn
import torch
# 论文:EMCAD: Efficient Multi-scale Convolutional Attention Decoding for Medical Image Segmentation, CVPR2024
# 论文地址:https://arxiv.org/pdf/2405.06880

def channel_shuffle(x, groups):
    batchsize, num_channels, height, width = x.data.size()
    channels_per_group = num_channels // groups
    # reshape
    x = x.view(batchsize, groups,
               channels_per_group, height, width)
    x = torch.transpose(x, 1, 2).contiguous()
    # flatten
    x = x.view(batchsize, -1, height, width)
    return x

def act_layer(act, inplace=False, neg_slope=0.2, n_prelu=1):
    # activation layer
    act = act.lower()
    if act == 'relu':
        layer = nn.ReLU(inplace)
    elif act == 'relu6':
        layer = nn.ReLU6(inplace)
    elif act == 'leakyrelu':
        layer = nn.LeakyReLU(neg_slope, inplace)
    elif act == 'prelu':
        layer = nn.PReLU(num_parameters=n_prelu, init=neg_slope)
    elif act == 'gelu':
        layer = nn.GELU()
    elif act == 'hswish':
        layer = nn.Hardswish(inplace)
    else:
        raise NotImplementedError('activation layer [%s] is not found' % act)
    return layer

# Efficient up-convolution block (EUCB)
class EUCB(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, activation='relu'):
        super(EUCB, self).__init__()

        self.in_channels = in_channels
        self.out_channels = out_channels
        self.up_dwc = nn.Sequential(
            nn.Upsample(scale_factor=2),
            nn.Conv2d(self.in_channels, self.in_channels, kernel_size=kernel_size, stride=stride,
                      padding=kernel_size // 2, groups=self.in_channels, bias=False),
            nn.BatchNorm2d(self.in_channels),
            act_layer(activation, inplace=True)
        )
        self.pwc = nn.Sequential(
            nn.Conv2d(self.in_channels, self.out_channels, kernel_size=1, stride=1, padding=0, bias=True)
        )

    def forward(self, x):
        x = self.up_dwc(x)
        x = channel_shuffle(x, self.in_channels)
        x = self.pwc(x)
        return x


if __name__ == '__main__':
    input = torch.randn(1, 32, 64, 64) #B C H W

    block = EUCB(in_channels=32, out_channels=64)

    print(input.size())

    output = block(input)    print(output.size())
### AI小怪兽EUCB算法实现及应用 #### EUCB算法简介 Epsilon Upper Confidence Bound (EUCB) 是一种用于解决多臂老虎机问题(Multi-Armed Bandit Problem, MABP) 的强化学习算法。该类算法旨在最大化累积奖励的同时最小化遗憾,即未选择最优策略所带来的损失。EUCB通过平衡探索(exploitation) 和利用(exploration),使得决策过程更加高效。 对于AI小怪兽而言,EUCB可以应用于个性化推荐系统、广告投放优化等领域。具体来说,在面对多个选项时(例如不同类型的怪物技能),EUCB可以帮助智能体快速找到最佳行动方案,从而提高整体性能表现[^1]。 #### EUCB算法原理 EUCB的核心思想是在每次迭代过程中计算各个动作的价值估计以及对应的置信区间上限,并选取当前具有最高上界的那一个作为下一步要执行的动作。随着试验次数增加,那些真正优秀的动作会被更多次尝试到;而对于较差的选择,则逐渐减少访问频率直至几乎不再考虑它们。这种机制有效地解决了MABP中存在的exploration-exploitation dilemma问题。 #### Python代码示例 下面给出一段简单的Python代码来展示如何实现基本版的EUCB算法: ```python import numpy as np from math import log, sqrt class EUcbBandit(object): def __init__(self, n_arms): self.n_arms = n_arms self.counts = [0] * n_arms # 记录每个arm被拉过的次数 self.values = [0.0] * n_arms # 存储每个arm的历史平均收益 def select_arm(self): t = sum(self.counts)+1 ucb_values = [ value + sqrt((2*log(t))/(count+1)) if count != 0 else float('inf') for value, count in zip(self.values, self.counts)] return int(np.argmax(ucb_values)) def update(self, chosen_arm, reward): self.counts[chosen_arm] += 1 n = self.counts[chosen_arm] value = self.values[chosen_arm] new_value = ((n - 1) / float(n)) * \ value + (1 / float(n)) * reward self.values[chosen_arm] = new_value ``` 此段程序定义了一个名为`EUcbBandit`的类,其中包含了两个主要函数:一个是用来决定下一个应该拉动哪个摇杆(`select_arm`);另一个则是更新选定摇杆后的反馈信息(`update`)。这里采用的是标准形式下的EUCB公式来进行上下界值的计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值