【Block总结】CPCA,通道优先卷积注意力|即插即用

论文信息

标题: Channel Prior Convolutional Attention for Medical Image Segmentation

论文链接: arxiv.org

代码链接: GitHub
在这里插入图片描述

创新点

本文提出了一种新的通道优先卷积注意力(CPCA)机制,旨在解决医学图像分割中存在的低对比度和显著器官形状变化等问题。CPCA通过在通道和空间维度上动态分配注意力权重,增强了模型对信息丰富通道和重要区域的关注能力。
在这里插入图片描述

方法

CPCA方法的核心在于以下几个方面:

  • 动态注意力分配: 在通道和空间维度上支持动态分配注意力权重,使得模型能够自适应地关注不同的特征。

  • 多尺度深度可分离卷积模块: 该模块有效提取空间关系,同时保持通道优先,增强了特征表示能力。

  • CPCANet网络结构: 基于CPCA的医学图像分割网络CPCANet被设计用于实现更高效的分割性能。

CPCA模块详解

通道优先卷积注意力(Channel Prior Convolutional Attention,CPCA)是一种新型的注意力机制,旨在提升深度学习模型在医学图像分割等任务中的性能。CPCA通过动态分配通道和空间维度的注意力权重,增强了模型对重要特征的关注能力。

CPCA结合了通道注意力和空间注意力的机制,具体实现步骤如下:

  1. 通道注意力(Channel Attention):

    • 特征聚合: 通过全局平均池化和全局最大池化操作,生成两个不同的特征表示。
    • 特征处理: 将这两个特征表示分别通过卷积层和激活函数处理,以提取通道之间的关系。
    • 权重生成: 通过Sigmoid函数生成通道注意力权重,用于动态调整每个通道的重要性。
  2. 空间注意力(Spatial Attention):

    • 空间关系捕捉: 使用多尺度深度可分离卷积模块来提取特征图中不同位置之间的关系。
    • 多尺度卷积: 采用不同大小的卷积核来捕获多尺度信息,从而更好地理解特征图的空间结构。
  3. 整体机制:

    • CPCA通过结合通道和空间注意力,动态分配注意力权重,并保持通道优先。这种结合使得网络能够更好地捕捉重要特征,提高特征的表征能力。

效果

在多个公开数据集上进行的实验表明,CPCANet相较于其他最先进的算法在分割性能上表现更佳,同时所需计算资源更少。具体来说,CPCA在处理低对比度和复杂形状变化的医学图像时,显著提高了分割精度。

实验结果

实验结果显示,CPCANet在两个主要数据集(如ACDC和ISIC2016)上均取得了优于现有方法的分割效果。通过对比分析,CPCA方法在多个指标上均表现出色,尤其是在处理复杂背景和形状变化时,展现了其优越性。

总结

本文通过提出通道优先卷积注意力(CPCA)机制,显著提升了医学图像分割的性能。CPCA不仅增强了模型对重要特征的关注能力,还通过动态分配注意力权重,优化了计算资源的使用。未来的研究可以进一步探索CPCA在其他领域的应用潜力,以及与其他深度学习技术的结合。

代码

import torch
import torch.nn.functional
import torch.nn.functional as F
from torch import nnclass Mlp(nn.Module):""" Multilayer perceptron."""def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):super().__init__()out_features = out_features or in_featureshidden_features = hidden_features or in_featuresself.fc1 = nn.Linear(in_features, hidden_features)self.act = act_layer()self.fc2 = nn.Linear(hidden_features, out_features)self.drop = nn.Dropout(drop)def forward(self, x):x = self.fc1(x)x = self.act(x)x = self.drop(x)x = self.fc2(x)x = self.drop(x)return xdef conv_bn(in_channels, out_channels, kernel_size, stride, padding, groups=1):result = nn.Sequential()result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels,kernel_size=kernel_size, stride=stride, padding=padding, groups=groups,bias=False))result.add_module('bn', nn.BatchNorm2d(num_features=out_channels))return resultdef conv_bn_relu(in_channels, out_channels, kernel_size, stride, padding, groups=1):result = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride,padding=padding, groups=groups)result.add_module('relu', nn.ReLU())return resultdef fuse_bn(conv_or_fc, bn):std = (bn.running_var + bn.eps).sqrt()t = bn.weight / stdt = t.reshape(-1, 1, 1, 1)if len(t) == conv_or_fc.weight.size(0):return conv_or_fc.weight * t, bn.bias - bn.running_mean * bn.weight / stdelse:repeat_times = conv_or_fc.weight.size(0) // len(t)repeated = t.repeat_interleave(repeat_times, 0)return conv_or_fc.weight * repeated, (bn.bias - bn.running_mean * bn.weight / std).repeat_interleave(repeat_times, 0)class ChannelAttention(nn.Module):def __init__(self, input_channels, internal_neurons):super(ChannelAttention, self).__init__()self.fc1 = nn.Conv2d(in_channels=input_channels, out_channels=internal_neurons, kernel_size=1, stride=1,bias=True)self.fc2 = nn.Conv2d(in_channels=internal_neurons, out_channels=input_channels, kernel_size=1, stride=1,bias=True)self.input_channels = input_channelsdef forward(self, inputs):x1 = F.adaptive_avg_pool2d(inputs, output_size=(1, 1))# print('x:', x.shape)x1 = self.fc1(x1)x1 = F.relu(x1, inplace=True)x1 = self.fc2(x1)x1 = torch.sigmoid(x1)x2 = F.adaptive_max_pool2d(inputs, output_size=(1, 1))# print('x:', x.shape)x2 = self.fc1(x2)x2 = F.relu(x2, inplace=True)x2 = self.fc2(x2)x2 = torch.sigmoid(x2)x = x1 + x2x = x.view(-1, self.input_channels, 1, 1)return xclass RepBlock(nn.Module):def __init__(self, in_channels, out_channels,channelAttention_reduce=4):super().__init__()self.C = in_channelsself.O = out_channelsassert in_channels == out_channelsself.ca = ChannelAttention(input_channels=in_channels, internal_neurons=in_channels // channelAttention_reduce)self.dconv5_5 = nn.Conv2d(in_channels, in_channels, kernel_size=5, padding=2, groups=in_channels)self.dconv1_7 = nn.Conv2d(in_channels, in_channels, kernel_size=(1, 7), padding=(0, 3), groups=in_channels)self.dconv7_1 = nn.Conv2d(in_channels, in_channels, kernel_size=(7, 1), padding=(3, 0), groups=in_channels)self.dconv1_11 = nn.Conv2d(in_channels, in_channels, kernel_size=(1, 11), padding=(0, 5), groups=in_channels)self.dconv11_1 = nn.Conv2d(in_channels, in_channels, kernel_size=(11, 1), padding=(5, 0), groups=in_channels)self.dconv1_21 = nn.Conv2d(in_channels, in_channels, kernel_size=(1, 21), padding=(0, 10), groups=in_channels)self.dconv21_1 = nn.Conv2d(in_channels, in_channels, kernel_size=(21, 1), padding=(10, 0), groups=in_channels)self.conv = nn.Conv2d(in_channels, in_channels, kernel_size=(1, 1), padding=0)self.act = nn.GELU()def forward(self, inputs):#   Global Perceptroninputs = self.conv(inputs)inputs = self.act(inputs)channel_att_vec = self.ca(inputs)inputs = channel_att_vec * inputsx_init = self.dconv5_5(inputs)x_1 = self.dconv1_7(x_init)x_1 = self.dconv7_1(x_1)x_2 = self.dconv1_11(x_init)x_2 = self.dconv11_1(x_2)x_3 = self.dconv1_21(x_init)x_3 = self.dconv21_1(x_3)x = x_1 + x_2 + x_3 + x_initspatial_att = self.conv(x)out = spatial_att * inputsout = self.conv(out)return outif __name__ == "__main__":dim=64# 如果GPU可用,将模块移动到 GPUdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 输入张量 (batch_size, height, width,channels)x = torch.randn(2,dim,40,40).to(device)# 初始化 CPCA模块block = RepBlock(dim,dim)print(block)block = block.to(device)# 前向传播output = block(x)print("输入:", x.shape)print("输出:", output.shape)

输出结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/69816.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python从零构建macOS状态栏应用(仿ollama)并集成AI同款流式聊天 API 服务(含打包为独立应用)

在本教程中,我们将一步步构建一个 macOS 状态栏应用程序,并集成一个 Flask 服务器,提供流式响应的 API 服务。 如果你手中正好持有一台 MacBook Pro,又怀揣着搭建 AI 聊天服务的想法,却不知从何处迈出第一步,那么这篇文章绝对是你的及时雨。 最终,我们将实现以下功能: …

强化学习、深度学习、深度强化学习的区别是什么?

前言 深度强化学习就是 深度学习 和 强化学习 的结合体。它让计算机程序(也就是智能体)在特定环境中不断尝试,从错误中学习,最终找到最优的行动策略。 深度学习是AlphaGo从棋谱里学习,强化学些Alphazero 学习规则&am…

string类(详解)

为什么学习string类? 1.1 C语言中的字符串 C语言中,字符串是以\0结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想&#xf…

【Redis】set 和 zset 类型的介绍和常用命令

1. set 1.1 介绍 set 类型和 list 不同的是,存储的元素是无序的,并且元素不允许重复,Redis 除了支持集合内的增删查改操作,还支持多个集合取交集,并集,差集 1.2 常用命令 命令 介绍 时间复杂度 sadd …

一些计算机零碎知识随写(25年2月)

今天复习 MySQL 的时候,我突然冒出一个想法:能不能远程连接 MySQL 呢?虽说心里清楚理论上可行,但一直没实际操作过。 于是,起床后我立马打开服务器,准备启动 MySQL。结果,这一启动就发现问题了&…

ESP32-c3实现获取土壤湿度(ADC模拟量)

1硬件实物图 2引脚定义 3使用说明 4实例代码 // 定义土壤湿度传感器连接的模拟输入引脚 const int soilMoisturePin 2; // 假设连接到GPIO2void setup() {// 初始化串口通信Serial.begin(115200); }void loop() {// 读取土壤湿度传感器的模拟值int sensorValue analogRead…

Java 大视界 -- Java 大数据在量子通信安全中的应用探索(69)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

86.(2)攻防世界 WEB PHP2

之前做过&#xff0c;回顾一遍&#xff0c;详解见下面这篇博客 29.攻防世界PHP2-CSDN博客 既然是代码审计题目&#xff0c;打开后又不显示代码&#xff0c;肯定在文件里 <?php // 首先检查通过 GET 请求传递的名为 "id" 的参数值是否严格等于字符串 "admi…

从理论到实践:Linux 进程替换与 exec 系列函数

个人主页&#xff1a;chian-ocean 文章专栏-Linux 前言&#xff1a; 在Linux中&#xff0c;进程替换&#xff08;Process Substitution&#xff09;是一个非常强大的特性&#xff0c;它允许将一个进程的输出直接当作一个文件来处理。这种技术通常用于Shell脚本和命令行操作中…

【数据结构】初识链表

顺序表的优缺点 缺点&#xff1a; 中间/头部的插入删除&#xff0c;时间复杂度效率较低&#xff0c;为O(N) 空间不够的时候需要扩容。 如果是异地扩容&#xff0c;增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间&#xff0c;会有不小的消耗。 扩容可能会存在…

增删改查(CRUD)操作

文章目录 MySQL系列&#xff1a;1.CRUD简介2.Create(创建)2.1单行数据全列插入2.2 单行数据指定插入2.3 多⾏数据指定列插⼊ 3.Retrieve(读取)3.1 Select查询3.1.1 全列查询3.1.2 指定列查询3.1.3 查询字段为表达式&#xff08;都是临时表不会对原有表数据产生影响&#xff09;…

使用Pygame制作“贪吃蛇”游戏

贪吃蛇 是一款经典的休闲小游戏&#xff1a;玩家通过操控一条会不断变长的“蛇”在屏幕中移动&#xff0c;去吃随机出现的食物&#xff0c;同时要避免撞到墙壁或自己身体的其他部分。由于其逻辑相对简单&#xff0c;但可玩性和扩展性都不错&#xff0c;非常适合作为新手练习游戏…

JavaScript闭包深入剖析:性能剖析与优化技巧

一、引言 在 JavaScript 的奇妙世界里&#xff0c;闭包无疑是一个既强大又迷人的特性。它就像是一把万能钥匙&#xff0c;为开发者打开了实现各种高级功能的大门。从数据封装与保护&#xff0c;到函数的记忆化&#xff0c;再到模块化开发&#xff0c;闭包都发挥着举足轻重的作…

蓝桥杯嵌入式赛道备考1 —— 基础GPIO实战

1. 点亮一个LED 蓝桥杯的板子资料的URL&#xff0c;笔者是从GitHub - JoyRiderJie/LanQiaoBei-QianRuShi拉去下来的。这个是Github仓库地址。 从应用层去玩一个开发板子&#xff0c;首先需要的是去尝试是点亮一个LED。让我们切换到手册《CT117E——产品手册》的第11页&#x…

浅析DNS污染及防范

DNS污染&#xff08;DNS Cache Poisoning&#xff09;是一种网络攻击手段&#xff0c;通过篡改DNS服务器的缓存数据&#xff0c;将域名解析结果指向错误的IP地址&#xff0c;从而误导用户访问恶意网站或无法访问目标网站。这种攻击利用了DNS协议的特性&#xff0c;例如“只认第…

AI编程:如何编写提示词

这是小卷对AI编程工具学习的第2篇文章&#xff0c;今天讲讲如何编写AI编程的提示词&#xff0c;并结合实际功能需求案例来进行开发 1.编写提示词的技巧 好的提示词应该是&#xff1a;目标清晰明确&#xff0c;具有针对性&#xff0c;能引导模型理解问题 下面是两条提示词的对…

linux asio网络编程理论及实现

最近在B站看了恋恋风辰大佬的asio网络编程&#xff0c;质量非常高。在本章中将对ASIO异步网络编程的整体及一些实现细节进行完整的梳理&#xff0c;用于复习与分享。大佬的博客&#xff1a;恋恋风辰官方博客 Preactor/Reactor模式 在网络编程中&#xff0c;通常根据事件处理的触…

【思维导图】并发编程

学习计划&#xff1a;将目前已经学的知识点串成一个思维导图。在往后的学习过程中&#xff0c;不断往思维导图里补充&#xff0c;形成自己整个知识体系。对于思维导图里的每个技术知识&#xff0c;自己用简洁的话概括出来&#xff0c; 训练自己的表达能力。 并发和并行的区别 并…

【B站保姆级视频教程:Jetson配置YOLOv11环境(四)cuda cudnn tensorrt配置】

Jetson配置YOLOv11环境&#xff08;4&#xff09;cuda cudnn tensorrt配置 文章目录 0. 简介1. cuda配置&#xff1a;添加cuda环境变量2. cudnn配置3. TensorRT Python环境配置3.1 系统自带Python环境中的TensorRT配置3.2 Conda 虚拟Python环境中的TensorRT配置 0. 简介 官方镜…

【深度分析】DeepSeek 遭暴力破解,攻击 IP 均来自美国,造成影响有多大?有哪些好的防御措施?

技术铁幕下的暗战&#xff1a;当算力博弈演变为代码战争 一场针对中国AI独角兽的全球首例国家级密码爆破&#xff0c;揭开了数字时代技术博弈的残酷真相。DeepSeek服务器日志中持续跳动的美国IP地址&#xff0c;不仅是网络攻击的地理坐标&#xff0c;更是技术霸权对新兴挑战者的…