YOLOv5、YOLOv8改进:SOCA注意力机制

news2024/11/18 17:25:50

    

目录

简介

2.YOLOv5使用SOCA注意力机制 

2.1增加以下SOCA.yaml文件

2.2common.py配置

2.3yolo.py配置


简介

注意力机制(Attention Mechanism)源于对人类视觉的研究。在认知科学中,由于信息处理的瓶颈,人类会选择性地关注所有信息的一部分,同时忽略其他可见的信息。为了合理利用有限的视觉信息处理资源,人类需要选择视觉区域中的特定部分,然后集中关注它。例如,人们在阅读时,通常只有少量要被读取的词会被关注和处理。综上,注意力机制主要有两个方面:决定需要关注输入的哪部分;分配有限的信息处理资源给重要的部分。这几年有关attention的论文与日俱增,下图就显示了在包括CVPR、ICCV、ECCV、NeurIPS、ICML和ICLR在内的顶级会议中,与attention相关的论文数量的增加量。下面我将会分享Yolov5 v6.1如何添加注意力机制;

  今天介绍一篇CPVR19的Oral文章,用二阶注意力网络来进行单图像超分辨率。作者来自清华深研院,鹏城实验室,香港理工大学以及阿里巴巴达摩院。

文章地址
github code

文章的出发点:现存的基于CNN的模型仍然面临一些限制:

  1. 大多数基于CNN的SR方法没有充分利用原始LR图像的信息,导致相当低的性能
  2. 大多数CNN-based models主要专注于设计更深或是更宽的网络,以学习更有判别力的高层特征,却很少发掘层间特征的内在相关性,从而妨碍了CNN的表达能

文章的大体思路:提出了一个深的二阶注意力网络SAN,以获得更好的特征表达和特征相关性学习。特别地,提出了一个二阶通道注意力机制SOCA来进行相关性学习。同时,提出了一个non-locally增强残差组NLRG来捕获长距离空间内容信息。

在这里插入图片描述

在LSRAG的末端,有一个SOCA模块,即二阶通道注意力机制。

相比于SENet里面的通道attention使用的是一阶统计信息(通过全局平均池化),本SOCA探索了二阶特征统计的attention

2.YOLOv5使用SOCA注意力机制 

2.1增加以下SOCA.yaml文件

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
   [-1, 1, SOCA, [1024]],

   [[17, 20, 24], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

2.2common.py配置

./models/common.py文件增加以下模块

import numpy as np
import torch
from torch import nn
from torch.nn import init

from torch.autograd import Function

class Covpool(Function):
     @staticmethod
     def forward(ctx, input):
         x = input
         batchSize = x.data.shape[0]
         dim = x.data.shape[1]
         h = x.data.shape[2]
         w = x.data.shape[3]
         M = h*w
         x = x.reshape(batchSize,dim,M)
         I_hat = (-1./M/M)*torch.ones(M,M,device = x.device) + (1./M)*torch.eye(M,M,device = x.device)
         I_hat = I_hat.view(1,M,M).repeat(batchSize,1,1).type(x.dtype)
         y = x.bmm(I_hat).bmm(x.transpose(1,2))
         ctx.save_for_backward(input,I_hat)
         return y
     @staticmethod
     def backward(ctx, grad_output):
         input,I_hat = ctx.saved_tensors
         x = input
         batchSize = x.data.shape[0]
         dim = x.data.shape[1]
         h = x.data.shape[2]
         w = x.data.shape[3]
         M = h*w
         x = x.reshape(batchSize,dim,M)
         grad_input = grad_output + grad_output.transpose(1,2)
         grad_input = grad_input.bmm(x).bmm(I_hat)
         grad_input = grad_input.reshape(batchSize,dim,h,w)
         return grad_input

class Sqrtm(Function):
     @staticmethod
     def forward(ctx, input, iterN):
         x = input
         batchSize = x.data.shape[0]
         dim = x.data.shape[1]
         dtype = x.dtype
         I3 = 3.0*torch.eye(dim,dim,device = x.device).view(1, dim, dim).repeat(batchSize,1,1).type(dtype)
         normA = (1.0/3.0)*x.mul(I3).sum(dim=1).sum(dim=1)
         A = x.div(normA.view(batchSize,1,1).expand_as(x))
         Y = torch.zeros(batchSize, iterN, dim, dim, requires_grad = False, device = x.device)
         Z = torch.eye(dim,dim,device = x.device).view(1,dim,dim).repeat(batchSize,iterN,1,1)
         if iterN < 2:
            ZY = 0.5*(I3 - A)
            Y[:,0,:,:] = A.bmm(ZY)
         else:
            ZY = 0.5*(I3 - A)
            Y[:,0,:,:] = A.bmm(ZY)
            Z[:,0,:,:] = ZY
            for i in range(1, iterN-1):
               ZY = 0.5*(I3 - Z[:,i-1,:,:].bmm(Y[:,i-1,:,:]))
               Y[:,i,:,:] = Y[:,i-1,:,:].bmm(ZY)
               Z[:,i,:,:] = ZY.bmm(Z[:,i-1,:,:])
            ZY = 0.5*Y[:,iterN-2,:,:].bmm(I3 - Z[:,iterN-2,:,:].bmm(Y[:,iterN-2,:,:]))
         y = ZY*torch.sqrt(normA).view(batchSize, 1, 1).expand_as(x)
         ctx.save_for_backward(input, A, ZY, normA, Y, Z)
         ctx.iterN = iterN
         return y
     @staticmethod
     def backward(ctx, grad_output):
         input, A, ZY, normA, Y, Z = ctx.saved_tensors
         iterN = ctx.iterN
         x = input
         batchSize = x.data.shape[0]
         dim = x.data.shape[1]
         dtype = x.dtype
         der_postCom = grad_output*torch.sqrt(normA).view(batchSize, 1, 1).expand_as(x)
         der_postComAux = (grad_output*ZY).sum(dim=1).sum(dim=1).div(2*torch.sqrt(normA))
         I3 = 3.0*torch.eye(dim,dim,device = x.device).view(1, dim, dim).repeat(batchSize,1,1).type(dtype)
         if iterN < 2:
            der_NSiter = 0.5*(der_postCom.bmm(I3 - A) - A.bmm(der_sacleTrace))
         else:
            dldY = 0.5*(der_postCom.bmm(I3 - Y[:,iterN-2,:,:].bmm(Z[:,iterN-2,:,:])) -
                          Z[:,iterN-2,:,:].bmm(Y[:,iterN-2,:,:]).bmm(der_postCom))
            dldZ = -0.5*Y[:,iterN-2,:,:].bmm(der_postCom).bmm(Y[:,iterN-2,:,:])
            for i in range(iterN-3, -1, -1):
               YZ = I3 - Y[:,i,:,:].bmm(Z[:,i,:,:])
               ZY = Z[:,i,:,:].bmm(Y[:,i,:,:])
               dldY_ = 0.5*(dldY.bmm(YZ) - 
                         Z[:,i,:,:].bmm(dldZ).bmm(Z[:,i,:,:]) - 
                             ZY.bmm(dldY))
               dldZ_ = 0.5*(YZ.bmm(dldZ) - 
                         Y[:,i,:,:].bmm(dldY).bmm(Y[:,i,:,:]) -
                            dldZ.bmm(ZY))
               dldY = dldY_
               dldZ = dldZ_
            der_NSiter = 0.5*(dldY.bmm(I3 - A) - dldZ - A.bmm(dldY))
         grad_input = der_NSiter.div(normA.view(batchSize,1,1).expand_as(x))
         grad_aux = der_NSiter.mul(x).sum(dim=1).sum(dim=1)
         for i in range(batchSize):
             grad_input[i,:,:] += (der_postComAux[i] \
                                   - grad_aux[i] / (normA[i] * normA[i])) \
                                   *torch.ones(dim,device = x.device).diag()
         return grad_input, None

def CovpoolLayer(var):
    return Covpool.apply(var)

def SqrtmLayer(var, iterN):
    return Sqrtm.apply(var, iterN)

class SOCA(nn.Module):
    # second-order Channel attention
    def __init__(self, channel, reduction=8):
        super(SOCA, self).__init__()
        self.max_pool = nn.MaxPool2d(kernel_size=2)

        self.conv_du = nn.Sequential(
            nn.Conv2d(channel, channel // reduction, 1, padding=0, bias=True),
            nn.ReLU(inplace=True),
            nn.Conv2d(channel // reduction, channel, 1, padding=0, bias=True),
            nn.Sigmoid()
        )

    def forward(self, x):
        batch_size, C, h, w = x.shape  # x: NxCxHxW
        N = int(h * w)
        min_h = min(h, w)
        h1 = 1000
        w1 = 1000
        if h < h1 and w < w1:
            x_sub = x
        elif h < h1 and w > w1:
            W = (w - w1) // 2
            x_sub = x[:, :, :, W:(W + w1)]
        elif w < w1 and h > h1:
            H = (h - h1) // 2
            x_sub = x[:, :, H:H + h1, :]
        else:
            H = (h - h1) // 2
            W = (w - w1) // 2
            x_sub = x[:, :, H:(H + h1), W:(W + w1)]
        cov_mat = CovpoolLayer(x_sub) # Global Covariance pooling layer
        cov_mat_sqrt = SqrtmLayer(cov_mat,5) # Matrix square root layer( including pre-norm,Newton-Schulz iter. and post-com. with 5 iteration)
        cov_mat_sum = torch.mean(cov_mat_sqrt,1)
        cov_mat_sum = cov_mat_sum.view(batch_size,C,1,1)
        y_cov = self.conv_du(cov_mat_sum)
        return y_cov*x

  

2.3yolo.py配置

在 models/yolo.py文件夹下

  • 定位到parse_model函数中 
  • 对应位置 下方只需要新增以下代码
    elif m is SOCA:
        c1, c2 = ch[f], args[0]
        if c2 != no:
            c2 = make_divisible(c2 * gw, 8)
        args = [c1, *args[1:]]
    

修改完成

如有遇到不清楚的地方欢迎评论区留言

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

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

相关文章

五款拿来就能用的炫酷表白代码

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 五款炫酷表白代码 1、无限弹窗表白2、做我女朋友好吗&#xff0c;不同意就关机3、…

增长黑武器|LTD营销SaaS荣获“2023亚太杰出营销数字化供应商”

LTD受邀与全球五百强企业数字化创新决策人&#xff0c;共同交流探讨信息化管理与数字化变革。 盛夏未央&#xff0c;八月笙箫已起&#xff0c;初秋登场。 在这烂漫的金秋时节&#xff0c;杭州乐通达网络有限公司&#xff08;简称&#xff1a;LTD&#xff09;受邀参加了“重建信…

【VS Code插件开发】Webview面板(三)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域优质作者、阿里云专家博主&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4e2; 资料领取&#xff1a;前端…

嵌入式设备应用开发(其他第三方库)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 前面我们介绍的qt、boost这些都是通用库。也就是说,不管什么样的场景,这些库都可以拿过来使用。然而在实际开发中还有一些第三方库,它是需要和实际场景联系在一起的。也就是说,…

百度千帆大模型初体验,接入30+大模型、100+提示词模版、插件最丰富,国内最强

大家好&#xff0c;我是二哥呀。 作为国内的头部大厂&#xff0c;百度在大模型这块的投入力度可以说非常大&#xff0c;3 月 16 号发布的大模型——文心一言可以说在业界激起了巨浪。 有支持的&#xff0c;当然也有怀疑的&#xff0c;但无论如何&#xff0c;百度勇敢的迈出去…

致敬,“编辑器之神”Vim的开发者Bram Moolenaar去世

编辑器之神Vim之父Bram Moolenaar逝世&#xff0c;享年62岁。其家人称&#xff0c;因过去几周里病情迅速恶化&#xff0c;Bram Moolenaar于8月3日去世。Bram的一生将大部分时间都奉献给了Vim&#xff0c;甚至在一个月前&#xff0c;他还在对Vim做着更新、修改工作。 Vim 是一个…

数据在内存中的储存·大小端(文字+画图详解)(c语言·超详细入门必看)

前言&#xff1a;Hello&#xff0c;大家好&#xff0c;我是心跳sy&#x1f618;&#xff0c;本节我们介绍c语言的两种基本的内置数据类型&#xff1a;数值类型和字符类型在内存中的储存方法&#xff0c;并对大小端进行详细介绍&#xff08;附两种大小端判断方法&#xff09;&am…

操作系统——进程和线程

文章目录 1.进程和线程的区别2.进程有哪几种状态?3.进程间的通信方式4.线程间的同步的方式5.进程的调度算法 1.进程和线程的区别 从上图可以看出&#xff1a;一个进程中可以有多个线程&#xff0c;多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)资源&#xff0c;但是每个…

块/ if else/ switch /for for each

1、块作用域&#xff0c; 定义在{}中的变量&#xff0c;只能在{}内生效 import java.util.*; public class Test{ public static void main(String[] xxx){int a10;if(a>9){int k 2;//k只在if{}内有效}//这个括号之后再对k进行操作&#xff0c;违法} } import java.util.…

Java之优雅处理 NullPointerException空指针异常

前言 NPE问题就是&#xff0c;我们在开发中经常碰到的NullPointerException。假设我们有两个类&#xff0c;他们的UML类图如下图所示 在这种情况下&#xff0c;有如下代码 user.getAddress().getProvince(); 这种写法&#xff0c;在user为null时&#xff0c;是有可能报Nul…

AI引擎助力,CamScanner智能高清滤镜开启扫描新纪元!

文章目录 ⭐ 写在前面⭐ 突破图像处理难点&#xff1a;扫描全能王的独特优势⭐ 耳听为虚&#xff0c;眼见为实⭐ 产品背后的主要核心&#xff1a;AI-Scan助力⭐ 深度学习助力智能文档处理的国际化进程⭐ 品味智能文档处理的轻松与精准 ⭐ 写在前面 在数字化快速发展的今天&…

CentOS6上安装MySQL8与Nginx开机自启

背景 临时在一台华为云的 CentOS6 上安装部署一个业务系统&#xff0c;这里记录下 MySQL 8 与 Nginx 的安装过程中遇到的问题。 CentOS6上安装MySQL8 # 下载 wget http://repo.mysql.com/yum/mysql-8.0-community/el/6/x86_64/mysql-community-common-8.0.19-1.el6.x86_64.r…

7-8 二分查找法

分数 10 全屏浏览题目 切换布局 作者 王跃萍 单位 东北石油大学 用二分法在一个有序数列{1,2,3,4,5,6,7,8,9,10}中查找key值&#xff0c;若找到key则输出其在数组中对应的下标&#xff0c;否则输出not found。 输入格式: 直接输入一个要查找的正整数key。没有其它任何附加…

并发-并发挑战及底层实现原理笔记

并发编程挑战 上下文切换 cpu通过给每个线程分配cpu时间片实现多线程执行&#xff0c;时间片是cpu分配给各个线程的时间&#xff0c;cpu通过不断切换线程执行。线程有创建和上下文切换的开销。减少上下文切换的方方法 – 无锁并发编程&#xff0c;eg&#xff1a;将数据的id按…

CSS中如何实现文字溢出省略号(text-overflow: ellipsis)效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS中如何实现文字溢出省略号&#xff08;text-overflow: ellipsis&#xff09;效果&#xff1f;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 …

16----公式

本节我们来学习如何在markdown中打印公式 Markdown是一种轻量级标记语言&#xff0c;常用于撰写文档、博客和论坛帖子。虽然Markdown本身并不支持数学公式&#xff0c;但可以使用一些扩展来实现公式的显示。在支持公式扩展的 Markdown 解析器中&#xff0c;我们可以使用 Katex …

【核磁共振成像】临床基本通用脉冲序列

目录 一、脉冲序列二、自旋回波(SE)脉冲序列2.1 自旋回波脉冲序列2.2 信噪比、差噪比2.3 采样2.4 改进的自旋回波变型序列 三、反向恢复(IR)脉冲序列3.1 反向恢复脉冲序列3.2 关于反向恢复脉冲序列的改进 四、梯度回波(GE)脉冲序列4.1 GE序列基本概念4.2 三维成像 五、相干稳态…

【Spring Boot 源码学习】自动装配流程源码解析(下)

自动装配流程源码解析&#xff08;下&#xff09; 引言往期内容主要内容4. 排除指定自动配置组件5. 过滤自动配置组件6. 触发自动配置事件 总结 引言 上篇博文&#xff0c;笔者带大家了解了自动装配流程中有关自动配置加载的流程&#xff1b; 本篇将介绍自动装配流程剩余的内…

【Freertos基础入门】同步互斥与通信

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、同步互斥与通信是什么&#xff1f;1.基础概念2.freertos通信可用的手段 二、同步与互斥的概念三、各类通信的区别与适用场景总结 前言 本系列基于stm32系列…

wustojc2005中英长度单位换算

#include <stdio.h> int main() {int n, inch;int foot;scanf("%d", &n);foot n /100.0/0.3048;inch (n/100.0/0.3048-foot)*12;printf("%d %d",foot,inch);return 0; }