YOLO11改进|编码器篇|引入AIFI混合特征编码器

news2024/11/17 12:35:03

在这里插入图片描述

目录

    • 一、【AIFI】混合编码器机制
      • 1.1【AIFI】混合编码器介绍
      • 1.2【AIFI】核心代码
    • 二、添加【AIFI】机制
      • 2.1STEP1
      • 2.2STEP2
      • 2.3STEP3
      • 2.4STEP4
    • 三、yaml文件与运行
      • 3.1yaml文件
      • 3.2运行成功截图

一、【AIFI】混合编码器机制

1.1【AIFI】混合编码器介绍

在这里插入图片描述

【AIFI】在论文中并没有结构图,让我们通过他的代码简单分析一下运行过程和优势

处理过程

  • 位置嵌入:
  • 2D Sine-Cosine 位置嵌入(build_2d_sincos_position_embedding):
    AIFI 模块首先为输入数据生成了 2D 的 sine-cosine 位置嵌入。这个嵌入机制类似于传统 Transformer 中的 positional encoding,用于补充序列中的位置信息,但在 AIFI 中,它针对二维图像结构,生成了与图像的宽度(w)和高度(h)相关的正弦和余弦嵌入。生成的位置嵌入在每个维度(w 和 h)分别通过 sine 和 cosine 函数来编码,通过交替使用 sin 和 cos,可以确保不同空间位置上的编码是唯一的。
  • 输入特征的处理:
  • 输入展平与转置:原始输入 x 的形状为 [batch_size, channels, height, width](即 [B, C, H, W])。在进入 Transformer 之前,AIFI 首先将输入展平并转置成 [B, HxW, C] 的形状,这符合 Transformer 的输入格式,转换后的形状将每个像素点的特征看作一个序列元素,并保持通道数为 C。
  • 位置嵌入也生成一个 [HxW, C] 的嵌入矩阵,与展平后的特征一起输入到 Transformer 中。
  • Transformer Encoder 层的应用:
  • 多头自注意力 (MultiheadAttention):输入展平后的特征进入 MultiheadAttention 层,进行自注意力计算。AIFI 模块继承自 TransformerEncoderLayer,在该层中,首先通过 q 和 k 进行查询和键的相似度计算,然后加权 v(值)得到新的特征表示。位置嵌入在此步骤中帮助网络学习到空间信息,从而增强不同位置之间的关联性。
  • 残差连接与前馈网络:在自注意力操作后,特征通过残差连接回输入特征,并经过一个两层前馈网络(Feedforward Network)进一步提升特征表达能力,最后通过 LayerNorm 和 Dropout 操作进行正则化和防止过拟合。
  • 恢复形状:
  • 还原维度:经过 Transformer 层处理后的特征,形状为 [B, HxW, C]。此时 AIFI 模块将其重新恢复到原始的 [B, C, H, W] 形状。这个步骤将序列形式的特征还原成二维的图像特征图,便于后续的卷积或其他图像处理操作。

AIFI 模块的优势

  • 二维位置嵌入的有效性:
    AIFI 模块引入了二维的 sine-cosine 位置嵌入,它可以有效捕捉图像中的空间结构和位置信息。这种位置嵌入方式具有简单、高效的特点,同时能提供位置信息给 Transformer 模块,帮助自注意力机制更好地学习空间上的关联性。与传统的 Transformer 位置嵌入(主要是处理1D序列)相比,AIFI 中的 2D 位置嵌入更适合处理图像数据。

  • 适应图像的序列建模:
    通过将图像展平为二维序列,AIFI 模块能够将 Transformer 应用于图像特征中,这使得网络能够学习跨位置的长距离依赖关系。自注意力机制可以在整个图像范围内捕捉到全局信息,这对提升模型的感知能力和整体表现非常有帮助。

  • Transformer 的全局建模能力:
    Transformer 的多头自注意力机制允许模型在不同位置之间建立全局依赖关系,这与传统的卷积网络只关注局部邻域不同。AIFI 的 Transformer 层能够有效整合图像中的全局特征,使得它在处理具有复杂上下文或长距离依赖的图像任务时非常有效。

  • 灵活的残差连接与归一化策略:
    AIFI 通过继承 TransformerEncoderLayer,使用了残差连接和 LayerNorm 归一化,这使得网络能够更深更稳定地训练,同时也避免了梯度消失问题。残差连接还可以保留原始输入特征,帮助网络平衡新旧特征。

  • 高效计算与参数共享:
    AIFI 通过使用 1x1 卷积和展平操作,使得整个模块在保持高效计算的同时,能够处理图像数据中潜在的上下文信息。通过位置编码和 Transformer 层的组合,AIFI 可以在不显著增加计算量的情况下获得较好的全局特征建模效果。

1.2【AIFI】核心代码

import torch
import torch.nn as nn


class TransformerEncoderLayer(nn.Module):
    """Defines a single layer of the transformer encoder."""

    def __init__(self, c1, cm=2048, num_heads=8, dropout=0.0, act=nn.GELU(), normalize_before=False):
        """Initialize the TransformerEncoderLayer with specified parameters."""
        super().__init__()
        self.ma = nn.MultiheadAttention(c1, num_heads, dropout=dropout, batch_first=True)
        # Implementation of Feedforward model
        self.fc1 = nn.Linear(c1, cm)
        self.fc2 = nn.Linear(cm, c1)

        self.norm1 = nn.LayerNorm(c1)
        self.norm2 = nn.LayerNorm(c1)
        self.dropout = nn.Dropout(dropout)
        self.dropout1 = nn.Dropout(dropout)
        self.dropout2 = nn.Dropout(dropout)

        self.act = act
        self.normalize_before = normalize_before

    @staticmethod
    def with_pos_embed(tensor, pos=None):
        """Add position embeddings to the tensor if provided."""
        return tensor if pos is None else tensor + pos

    def forward_post(self, src, src_mask=None, src_key_padding_mask=None, pos=None):
        """Performs forward pass with post-normalization."""
        q = k = self.with_pos_embed(src, pos)
        src2 = self.ma(q, k, value=src, attn_mask=src_mask, key_padding_mask=src_key_padding_mask)[0]
        src = src + self.dropout1(src2)
        src = self.norm1(src)
        src2 = self.fc2(self.dropout(self.act(self.fc1(src))))
        src = src + self.dropout2(src2)
        return self.norm2(src)

    def forward_pre(self, src, src_mask=None, src_key_padding_mask=None, pos=None):
        """Performs forward pass with pre-normalization."""
        src2 = self.norm1(src)
        q = k = self.with_pos_embed(src2, pos)
        src2 = self.ma(q, k, value=src2, attn_mask=src_mask, key_padding_mask=src_key_padding_mask)[0]
        src = src + self.dropout1(src2)
        src2 = self.norm2(src)
        src2 = self.fc2(self.dropout(self.act(self.fc1(src2))))
        return src + self.dropout2(src2)

    def forward(self, src, src_mask=None, src_key_padding_mask=None, pos=None):
        """Forward propagates the input through the encoder module."""
        if self.normalize_before:
            return self.forward_pre(src, src_mask, src_key_padding_mask, pos)
        return self.forward_post(src, src_mask, src_key_padding_mask, pos)


class AIFI(TransformerEncoderLayer):
    """Defines the AIFI transformer layer."""

    def __init__(self, c1, cm=2048, num_heads=8, dropout=0, act=nn.GELU(), normalize_before=False):
        """Initialize the AIFI instance with specified parameters."""
        super().__init__(c1, cm, num_heads, dropout, act, normalize_before)

    def forward(self, x):
        """Forward pass for the AIFI transformer layer."""
        c, h, w = x.shape[1:]
        pos_embed = self.build_2d_sincos_position_embedding(w, h, c)
        # Flatten [B, C, H, W] to [B, HxW, C]
        x = super().forward(x.flatten(2).permute(0, 2, 1), pos=pos_embed.to(device=x.device, dtype=x.dtype))
        return x.permute(0, 2, 1).view([-1, c, h, w]).contiguous()

    @staticmethod
    def build_2d_sincos_position_embedding(w, h, embed_dim=256, temperature=10000.0):
        """Builds 2D sine-cosine position embedding."""
        grid_w = torch.arange(int(w), dtype=torch.float32)
        grid_h = torch.arange(int(h), dtype=torch.float32)
        grid_w, grid_h = torch.meshgrid(grid_w, grid_h, indexing='ij')
        assert embed_dim % 4 == 0, \
            'Embed dimension must be divisible by 4 for 2D sin-cos position embedding'
        pos_dim = embed_dim // 4
        omega = torch.arange(pos_dim, dtype=torch.float32) / pos_dim
        omega = 1. / (temperature ** omega)

        out_w = grid_w.flatten()[..., None] @ omega[None]
        out_h = grid_h.flatten()[..., None] @ omega[None]

        return torch.cat([torch.sin(out_w), torch.cos(out_w), torch.sin(out_h), torch.cos(out_h)], 1)[None]

二、添加【AIFI】机制

2.1STEP1

首先找到ultralytics/nn文件路径下新建一个Add-module的python文件包【这里注意一定是python文件包,新建后会自动生成_init_.py】,如果已经跟着我的教程建立过一次了可以省略此步骤,随后新建一个AIFI.py文件并将上文中提到的注意力机制的代码全部粘贴到此文件中,如下图所示在这里插入图片描述

2.2STEP2

在STEP1中新建的_init_.py文件中导入增加改进模块的代码包如下图所示在这里插入图片描述

2.3STEP3

找到ultralytics/nn文件夹中的task.py文件,在其中按照下图添加在这里插入图片描述

2.4STEP4

定位到ultralytics/nn文件夹中的task.py文件中的def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)函数添加如图代码,【如果不好定位可以直接ctrl+f搜索定位】

在这里插入图片描述

三、yaml文件与运行

3.1yaml文件

以下是添加【AIFI】机制在Backbone中的yaml文件,大家可以注释自行调节,效果以自己的数据集结果为准

# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLO11 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect

# Parameters
nc: 80 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolo11n.yaml' will call yolo11.yaml with scale 'n'
  # [depth, width, max_channels]
  n: [0.50, 0.25, 1024] # summary: 319 layers, 2624080 parameters, 2624064 gradients, 6.6 GFLOPs
  s: [0.50, 0.50, 1024] # summary: 319 layers, 9458752 parameters, 9458736 gradients, 21.7 GFLOPs
  m: [0.50, 1.00, 512] # summary: 409 layers, 20114688 parameters, 20114672 gradients, 68.5 GFLOPs
  l: [1.00, 1.00, 512] # summary: 631 layers, 25372160 parameters, 25372144 gradients, 87.6 GFLOPs
  x: [1.00, 1.50, 512] # summary: 631 layers, 56966176 parameters, 56966160 gradients, 196.0 GFLOPs

# YOLO11n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
  - [-1, 2, C3k2, [256, False, 0.25]]
  - [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
  - [-1, 2, C3k2, [512, False, 0.25]]
  - [-1, 1, Conv, [512, 3, 2]] # 5-P4/16
  - [-1, 2, C3k2, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]] # 7-P5/32
  - [-1, 2, C3k2, [1024, True]]
  - [-1, 1, AIFI, [1024, 8]] # 9
  - [-1, 2, C2PSA, [1024]] # 10

# YOLO11n head
head:
  - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  - [[-1, 6], 1, Concat, [1]] # cat backbone P4
  - [-1, 2, C3k2, [512, False]] # 13

  - [-1, 1, nn.Upsample, [None, 2, "nearest"]]
  - [[-1, 4], 1, Concat, [1]] # cat backbone P3
  - [-1, 2, C3k2, [256, False]] # 16 (P3/8-small)


  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 13], 1, Concat, [1]] # cat head P4
  - [-1, 2, C3k2, [512, False]] # 19 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 10], 1, Concat, [1]] # cat head P5
  - [-1, 2, C3k2, [1024, True]] # 22 (P5/32-large)

  - [[16, 19, 22], 1, Detect, [nc]] # Detect(P3, P4, P5)

以上添加位置仅供参考,具体添加位置以及模块效果以自己的数据集结果为准

3.2运行成功截图

在这里插入图片描述

OK 以上就是添加【AIFI】编码器机制的全部过程了,后续将持续更新尽情期待

在这里插入图片描述

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

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

相关文章

CVPR 2024最佳论文候选-pixelSplat论文解读

目录 一、概述 二、相关工作 1、单场景下的视角合成 2、基于先验的三维重建和视图合成 3、多视图几何测量 三、3DGS的缺点 1、容易陷入最小值 2、需要大量输入图像 3、尺度模糊性 四、pixelSplat 1、解决尺度模糊性(深度信息生成) 2、编码器…

QT实现QMessageBox中文按钮

这是我记录Qt学习过程心得文章的第二篇,主要是为了方便QMessageBox弹出框的使用,通过自定义的方式,将其常用的功能,统一封装成一个函数,还是写在了Skysonya类里面。 实现代码: //中文提示对话框 bool Sky…

线程(四)线程的同步——条件变量

文章目录 线程线程的同步和互斥线程同步--条件变量什么是线程同步示例--条件变量的使用示例--使用两个线程对同一个文件进行读写示例--一个读者一个写者使用条件变量来实现同步 线程 线程的同步和互斥 线程同步–条件变量 是一个宏观概念,在微观上包含线程的相互…

新160个crackme - 078-CodeZero.1

运行分析 需要破解Serial PE分析 VB程序,32位,无壳 静态分析&动态调试 使用VB Decompiler进行分析找到check按钮事件: Form1 -> Command1_Click_4055F4发现直接爆出了Serial55555 验证成功

【xilinx-versal】【Petalinux】I2C驱动开发问题记录

问题 调试中发现系统起来后无I2C设备。 仔细查找后发现没有配置versal的I2C控制器。 解决方法 打开versal的I2C控制器的配置 起来后I2C设备注册成功

Acwing 区间问题

Acwing 905.区间选点 实现思路: 将每个区间按照右端点从小到大排序从前往后依次枚举每个区间 若当前区间中已经包含点,则跳过;否则(即当前区间的左端点大于该点),选择当前区间的右端点; 证明&a…

设计模式:单例

一.什么是单例模式 单例模式是一种设计模式,指在整个程序生命周期中有且仅有一个实例的类。可以分为懒汉式以及饿汉式。 懒汉式:只有在类的实例被使用时才生成唯一实例。但是存在线程安全以及内存泄露的问题。可以节省系统资源。 饿汉式:程序…

《Oracle DB备份与恢复》:一文千字教你掌握备份基础知识

** List item 备份需要扎实掌握基础知识,这样才能规划好适合自己的备份恢复策略,才能在出故障的时候不慌不忙,从容应付。 好了不多逼逼了,直接上干货。** 1. 备份分类: 备份根据性质和目的不同分为以下几种&#…

车辆路径规划问题(VRP)优化方案

车辆路径规划问题(VRP)优化方案 车辆路径规划问题(Vehicle Routing Problem, VRP)是物流领域中一个经典的组合优化问题,目标是在满足客户需求的情况下,找到一组车辆的最优配送路径,以最小化总的…

如何让员工意识到六西格玛项目对公司和个人的长期利益?

当下,六西格玛作为一种以数据驱动的管理方法论,正逐步成为许多企业实现卓越运营的重要工具。然而,要让员工深刻认识到六西格玛项目不仅对公司长远发展至关重要,也对他们个人职业生涯有着深远的积极影响,并非易事。下面…

C++ day05(模版与容器)

目录 【1】模版 template 1》概念 2》函数模版 3》类模版 【2】容器 1》STL标准模版库 2》容器的概念 3》顺序容器 1> arrry(C11) 2> vector 3> list 4> deque 4》 关联容器 5》迭代器 iterator 【1】模版 template 1》概念 C模版可以让类或函数声…

javacpp调用pdfium的c++动态库

1、.h头文件 2、生成java代码的conf PdfiumDocumentConfigure.java package org.swdc.pdfium.conf;import org.bytedeco.javacpp.annotation.Platform; import org.bytedeco.javacpp.annotation.Properties; import org.bytedeco.javacpp.tools.InfoMap; import org.byte…

网络知识点之—EVPN

EVPN(Ethernet Virtual Private Network)是下一代全业务承载的VPN解决方案。EVPN统一了各种VPN业务的控制面,利用BGP扩展协议来传递二层或三层的可达性信息,实现了转发面和控制面的分离。 EVPN解决传统L2VPN的无法实现负载分担、…

springboot+vue前后端分离-使用腾讯云服务器部署网站

项目打包 参考链接 CSDN springboot打包 idea默认新建的shell窗口在项目根目录位置,可以看到项目根目录下有mvnw HELP.md log mvnw mvnw.cmd pom.xml src target./mvnw clean package -Dmaven.test…

Kali Linux中安装配置影音资源下载神器Amule

一、Debian系列Linux安装amule命令: sudo apt update sudo apt-get install amule amule-utils 二、配置Amule的要点: 1、首次运行Amule,提示是否下载服务器列表,点击是。 2、搜索选项的类型选择全球,类型的默认选项…

数据恢复与数据取证:Visual NAND Reconstructor 闪存数据恢复工具

天津鸿萌科贸发展有限公司是专业闪存数据恢复工具 VNR (Visual NAND Reconstructor) 的授权代理商。 VNR(Visual NAND Reconstructor)可视化 NAND 重建工具套件由硬件和软件构成。其中硬件部分包含 NAND 读卡器和一组用于不同 NAND 芯片封装的适配器。读…

LeetCode 48 Rotate Image 解题思路和python代码

题目: You are given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise). You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and …

序列化流和反序列化流

序列化流 ObjectOutputStream 序列化流/对象操作输出流 包装基本流,属于字节流的一种,负责输出数据。可以把Java中的对象写到本地文件中去。 构造方法: public ObjectOutputStream(OutputStream out)把基本流包装成高…

【Java 并发编程】解决多线程中数据错乱问题

前言 承接上回,我们已经理解了线程的一些相关操作,本篇内容将会讲到如何去解决线程竞争导致的数据错乱。 前期回顾:线程操作 目录 前言 线程竞争的场景 竞态条件的详解 synchronized 关键字 ReentrantLock 类 线程竞争的场景 概念&#xff1a…

异步场景: promise、async函数与await命令介绍

如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。 在鸿蒙的开发中,我们时常会遇到promise异步场景,有同学反馈说…