news 2026/4/18 10:21:13

YOLOv8改进 - 注意力机制 | CPCA (Channel Prior Convolutional Attention) 通道先验卷积注意力通过动态权重分配增强复杂场景特征感知

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv8改进 - 注意力机制 | CPCA (Channel Prior Convolutional Attention) 通道先验卷积注意力通过动态权重分配增强复杂场景特征感知

前言

本文介绍了通道先验卷积注意力(CPCA)及其在YOLOv8中的结合应用。医学图像分割面临挑战,现有注意力机制效果不佳,CPCA应运而生。它结合通道注意力和空间注意力,通过多尺度深度可分离卷积模块提取空间关系并保留通道先验。通道注意力学习通道重要性,空间注意力捕捉位置关系。我们将CPCA代码引入指定目录,在ultralytics/nn/tasks.py中注册,配置yolov8-CPCA.yaml文件,最后经实验脚本和结果验证了改进的有效性。

文章目录: YOLOv8改进大全:卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总

专栏链接: YOLOv8改进专栏

文章目录

  • 前言
  • 介绍
    • 摘要
  • 文章链接
  • 基本原理
  • 通道注意力模块
  • 核心代码
    • 引入代码
    • tasks注册
      • 步骤1:
      • 步骤2
    • 配置yolov8-CPCA.yaml
  • 实验
    • 脚本
    • 结果

介绍

摘要

医学图像通常展示出低对比度和显著的器官形状变化等特征。现有注意力机制通常不足以适应性地提升医学成像的分割性能。本文提出了一种有效的通道优先卷积注意力(CPCA)方法,支持在通道和空间维度上动态分配注意力权重。通过采用多尺度深度卷积模块,有效地提取空间关系同时保留通道优先。CPCA具有关注信息丰富通道和重要区域的能力。基于CPCA,我们提出了一个用于医学图像分割的网络,称为CPCANet。CPCANet在两个公开可用的数据集上进行了验证。与最先进的算法相比,CPCANet在需求较少的计算资源下实现了改进的分割性能。我们的代码已公开可用于https://github.com/Cuthbert-Huang/CPCANet。

文章链接

论文地址:论文地址

代码地址:代码地址

基本原理

通道先验卷积注意力(Channel Prior Convolutional Attention,CPCA)是一种用于增强特征表示和动态分配注意力权重的注意力机制。CPCA结合了通道注意力和空间注意力,通过多尺度深度可分离卷积模块有效地提取空间关系并保留通道先验。下面是CPCA的详细技术原理:

  1. 通道注意力(Channel Attention)
    • 通道注意力模块用于动态学习每个通道的重要性,以提高特征的表征能力。通道注意力通过以下步骤实现:
      • 对输入特征进行全局平均池化和全局最大池化,得到两个不同的特征表示。
      • 将这两个特征表示分别通过两个卷积层和激活函数处理,以提取通道之间的关系。
      • 将处理后的特征通过Sigmoid函数生成通道注意力权重,用于动态调整每个通道的重要性。
  2. 空间注意力(Spatial Attention)
    • 空间注意力模块用于捕捉特征图中不同位置之间的关系,以提高空间信息的表征。空间注意力通过多尺度深度可分离卷积模块实现,可以有效地提取空间关系。
    • 多尺度深度可分离卷积模块使用不同大小的卷积核来捕获多尺度信息,从而更好地理解特征图的空间结构。
  3. CPCA的整体原理
    • CPCA结合了通道注意力和空间注意力,通过多尺度深度可分离卷积模块实现动态分配注意力权重,并保留通道先验。这种结合可以帮助网络更好地捕捉重要的特征,并提高特征的表征能力。

通道注意力模块

**通道注意力:沿袭了 CBAM 的方法,**采用平均池和最大池操作,从特征映射中聚集空间信息,然后再输入共享的 MLP 中:

𝐶𝐴(𝐹)=σ(𝑀𝐿𝑃(𝐴𝑣𝑔𝑃𝑜𝑜𝑙(𝐹))+𝑀𝐿𝑃(𝑀𝑎𝑥𝑃𝑜𝑜𝑙(𝐹)))

其中 σ 是 sigmoid。

具体来说,通道注意力模块的代码实现包括以下步骤:

  1. 对输入特征进行平均池化和最大池化操作,得到两个池化后的特征表示。
  2. 将两个池化后的特征表示分别通过两个卷积层和ReLU激活函数处理,以提取特征之间的关系。
  3. 将处理后的特征通过torch.sigmoid函数生成通道注意力权重,用于动态调整每个通道的重要性。
  4. 最终将通道注意力权重应用到输入特征上,得到经过通道注意力处理后的特征表示。

核心代码

classChannelAttention(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_channelsdefforward(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+x2 x=x.view(-1,self.input_channels,1,1)returnxclassRepBlock(nn.Module):def__init__(self,in_channels,out_channels,channelAttention_reduce=4):super().__init__()self.C=in_channels self.O=out_channelsassertin_channels==out_channels self.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()defforward(self,inputs):# Global Perceptroninputs=self.conv(inputs)inputs=self.act(inputs)channel_att_vec=self.ca(inputs)inputs=channel_att_vec*inputs x_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_init spatial_att=self.conv(x)out=spatial_att*inputs out=self.conv(out)returnout

引入代码

在根目录下的ultralytics/nn/目录,新建一个attention目录,然后新建一个以CPCA为文件名的py文件, 把代码拷贝进去。

importtorchimporttorch.nnasnnimporttorch.nn.functionalasFclassChannelAttention(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_channelsdefforward(self,inputs):x1=F.adaptive_avg_pool2d(inputs,output_size=(1,1))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))x2=self.fc1(x2)x2=F.relu(x2,inplace=True)x2=self.fc2(x2)x2=torch.sigmoid(x2)x=x1+x2 x=x.view(-1,self.input_channels,1,1)returninputs*xclassCPCA(nn.Module):def__init__(self,channels,channelAttention_reduce=4):super().__init__()self.ca=ChannelAttention(input_channels=channels,internal_neurons=channels//channelAttention_reduce)self.dconv5_5=nn.Conv2d(channels,channels,kernel_size=5,padding=2,groups=channels)self.dconv1_7=nn.Conv2d(channels,channels,kernel_size=(1,7),padding=(0,3),groups=channels)self.dconv7_1=nn.Conv2d(channels,channels,kernel_size=(7,1),padding=(3,0),groups=channels)self.dconv1_11=nn.Conv2d(channels,channels,kernel_size=(1,11),padding=(0,5),groups=channels)self.dconv11_1=nn.Conv2d(channels,channels,kernel_size=(11,1),padding=(5,0),groups=channels)self.dconv1_21=nn.Conv2d(channels,channels,kernel_size=(1,21),padding=(0,10),groups=channels)self.dconv21_1=nn.Conv2d(channels,channels,kernel_size=(21,1),padding=(10,0),groups=channels)self.conv=nn.Conv2d(channels,channels,kernel_size=(1,1),padding=0)self.act=nn.GELU()defforward(self,inputs):# Global Perceptroninputs=self.conv(inputs)inputs=self.act(inputs)#在应用通道注意力后直接改变特征,使得后续卷积操作在经过注意力机制的特征图上进行。这样的结构可能更注重通过注意力机制得到的特征,并在此基础上进一步提取多尺度信息inputs=self.ca(inputs)# 通过通道注意力调整输入特征,然后在经过多个不同尺度的卷积之后,进行特征叠加。该结构更适合在需要强调原始特征和不同尺度特征组合的场景中使用# channel_att_vec = self.ca(inputs) # 调用通道注意力,得到每一个通道的权值# inputs = channel_att_vec * inputs # 与输入相乘,得到论文定义的通道先验信息x_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_init spatial_att=self.conv(x)out=spatial_att*inputs out=self.conv(out)returnout

tasks注册

ultralytics/nn/tasks.py中进行如下操作:

步骤1:

fromultralytics.nn.attention.CPCAimportCPCA

步骤2

修改def parse_model(d, ch, verbose=True):

CPCA

配置yolov8-CPCA.yaml

ultralytics/cfg/models/v8/yolov8-CPCA.yaml

# Ultralytics YOLO 🚀, AGPL-3.0 license# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect# Parametersnc:80# number of classesscales:# model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'# [depth, width, max_channels]n:[0.33,0.25,1024]s:[0.33,0.50,1024]m:[0.67,0.75,768]l:[1.00,1.00,512]x:[1.00,1.25,512]backbone:# [from, repeats, module, args]-[-1,1,Conv,[64,3,2]]# 0-P1/2-[-1,1,Conv,[128,3,2]]# 1-P2/4-[-1,3,C2f,[128,True]]-[-1,1,Conv,[256,3,2]]# 3-P3/8-[-1,6,C2f,[256,True]]-[-1,1,Conv,[512,3,2]]# 5-P4/16-[-1,6,C2f,[512,True]]-[-1,1,Conv,[1024,3,2]]# 7-P5/32-[-1,3,C2f,[1024,True]]-[-1,1,SPPF,[1024,5]]# 9head:-[-1,1,nn.Upsample,[None,2,'nearest']]-[[-1,6],1,Concat,[1]]# cat backbone P4-[-1,3,C2f,[512]]# 12-[-1,1,nn.Upsample,[None,2,'nearest']]-[[-1,4],1,Concat,[1]]# cat backbone P3-[-1,3,C2f,[256]]# 15 (P3/8-small)-[-1,3,CPCA,[256]]# 16-[-1,1,Conv,[256,3,2]]-[[-1,12],1,Concat,[1]]# cat head P4-[-1,3,C2f,[512]]# 19 (P4/16-medium)-[-1,3,CPCA,[512]]-[-1,1,Conv,[512,3,2]]-[[-1,9],1,Concat,[1]]# cat head P5-[-1,3,C2f,[1024]]# 23 (P5/32-large)-[-1,3,CPCA,[1024]]-[[16,20,24],1,Detect,[nc]]# Detect(P3, P4, P5)

实验

脚本

import os from ultralytics import YOLO yaml = 'ultralytics/cfg/models/v8/yolov8-CPCA.yaml' model = YOLO(yaml) model.info()if __name__ == "__main__":results = model.train(data='coco128.yaml',name='CPCA',epochs=10,workers=8,batch=1)

结果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 22:09:03

6大AI论文优化工具横向测评:从语言流畅度到学术规范全覆盖

开头总结工具对比(技能4) �� 为帮助学生们快速选出最适合的AI论文工具,我从处理速度、降重效果和核心优势三个维度,对比了6款热门网站,数据基于实际使用案例: 工具名称 处理速度 降…

作者头像 李华
网站建设 2026/4/18 7:05:25

Mac搜索文件后快速锁定目录:全场景实用技巧汇总

Mac搜索文件后快速锁定目录:全场景实用技巧汇总 在使用Mac时,我们常通过聚焦搜索(Spotlight)或访达(Finder)快速找到目标文件,但找到文件后“找不到其存储目录”的困扰却很常见。无论是想整理文…

作者头像 李华
网站建设 2026/4/16 18:00:57

React的代理配置

方法一: 在package.json中追加如下配置 "proxy":"http://localhost:5000" 说明: 1.优点:配置简单,前端请求资源时可以不加任何前缀。 2.缺点:不能配置多个代理。 3.工作方式:上述方式配置代理,当请求了3000不存在的资源时,那么该请求会转发给…

作者头像 李华
网站建设 2026/4/18 2:36:02

人群仿真软件:Legion_(13).Legion仿真项目管理

Legion仿真项目管理 项目创建与初始化 在使用Legion进行人群仿真时,首先需要创建一个新的项目并进行初始化。项目创建的过程包括定义仿真场景、设置仿真参数、导入必要的数据文件等。本节将详细介绍如何在Legion中创建和初始化一个仿真项目。 1. 创建新项目 1.1 通过…

作者头像 李华
网站建设 2026/4/18 8:15:04

大模型智能体(Agent)完全指南:规划、工具与记忆的工程化实践

智能体是具备规划、执行、学习能力的智能系统。本文系统解析了智能体的三大核心能力:规划(任务拆解与自我反思)、工具使用(从函数调用到统一标准)、记忆(短期与长期记忆),并提供了从概念到系统的工程化构建路线图,强调未来竞争在于工程架构深…

作者头像 李华
网站建设 2026/4/18 3:36:16

告别课程论文凑字数!虎贲等考 AI 让千字论文也能有硬核学术感

学期末的课程论文,堪称大学生的 “期末劫”:选题要么撞车泛泛而谈,要么冷门到找不到文献支撑;文献综述东拼西凑像流水账;好不容易写完初稿,查重率超标、AI 痕迹明显的问题又接踵而至。 别再为课程论文熬夜…

作者头像 李华