当前位置: 首页 > news >正文

一种改进DEIM(CVPR2025)的简单示例

本文为一个改进DEIM模型的简单示例。

1 源码准备

于github下载DEIM源码。

并自行寻找可用于替换DEIM原有模块的改进模块,或自行设计模块。

2 改进模块

以DEIM_DFine模型的hybridencoder-transformerlayer为例。

在engine/deim/hybrid_encoder.py中找到hybridencoder类。

我们要改进其中的transformerlayer

class TransformerEncoderLayer(nn.Module):def __init__(self,d_model,    nhead,  dim_feedforward=2048,dropout=0.1, activation="relu",    normalize_before=False):  super().__init__()  self.normalize_before = normalize_beforeself.self_attn = nn.MultiheadAttention(d_model, nhead, dropout, batch_first=True) self.linear1 = nn.Linear(d_model, dim_feedforward)   self.dropout = nn.Dropout(dropout)    self.linear2 = nn.Linear(dim_feedforward, d_model)self.norm1 = nn.LayerNorm(d_model)self.norm2 = nn.LayerNorm(d_model)    self.dropout1 = nn.Dropout(dropout)     self.dropout2 = nn.Dropout(dropout) self.activation = get_activation(activation)  @staticmethoddef with_pos_embed(tensor, pos_embed):    return tensor if pos_embed is None else tensor + pos_embed     def forward(self, src, src_mask=None, pos_embed=None) -> torch.Tensor:    residual = src   if self.normalize_before:     src = self.norm1(src)q = k = self.with_pos_embed(src, pos_embed)src, _ = self.self_attn(q, k, value=src, attn_mask=src_mask)src = residual + self.dropout1(src)     if not self.normalize_before:    src = self.norm1(src)residual = src  if self.normalize_before:src = self.norm2(src)   src = self.linear2(self.dropout(self.activation(self.linear1(src))))    src = residual + self.dropout2(src) if not self.normalize_before:src = self.norm2(src)    return src

新建一个类,命名按照自己的习惯,并继承原类。部分代码示例如下:

class TransformerEncoderLayer_imporvedNorm(TransformerEncoderLayer):def __init__(self,d_model,nhead,dim_feedforward=2048,dropout=0.1,activation="relu",normalize_before=False):super().__init__(d_model, nhead, dim_feedforward, dropout, activation, normalize_before)

新的类继承了原TransformerEncoderLayer类中的方法,因此仅重新定义需要改进的组件即可,不需要变动的组件代码无需重复写。

同样的,对于hybridencoder类。修改encoder_layer和encoder中的组件名。


@register()
class HybridEncoder_improved(HybridEncoder):__share__ = ['eval_spatial_size', ]def __init__(self,in_channels=[512, 1024, 2048],  # 输入特征图的通道数列表,例如来自骨干网络的不同层feat_strides=[8, 16, 32],  # 输入特征图的步幅列表,表示特征图相对于输入图像的缩放比例hidden_dim=256,  # 隐藏层维度,所有特征图将被投影到这个维度nhead=8,  # Transformer 编码器中多头自注意力的头数dim_feedforward=1024,  # Transformer 编码器中前馈网络的维度dropout=0.0,  # Transformer 编码器中的 dropout 概率enc_act='gelu',  # Transformer 编码器中的激活函数类型use_encoder_idx=[2],  # 指定哪些层使用 Transformer 编码器(索引列表)num_encoder_layers=1,  # Transformer 编码器的层数pe_temperature=10000,  # 位置编码的温度参数,用于控制频率expansion=1.0,  # FPN 和 PAN 中特征扩展因子depth_mult=1.0,  # 深度乘数,用于调整网络深度act='silu',  # FPN 和 PAN 中使用的激活函数类型eval_spatial_size=None,  # 评估时的空间尺寸 (H, W),用于预计算位置编码version='dfine',  # 模型版本,决定使用哪些具体模块(如 'dfine' 或其他)):# 调用父类 nn.Module 的构造函数super().__init__(in_channels, feat_strides, hidden_dim, nhead, dim_feedforward, dropout, enc_act,use_encoder_idx,num_encoder_layers, pe_temperature, expansion, depth_mult, act, eval_spatial_size, version)self.in_channels = in_channels  # 输入通道数列表self.feat_strides = feat_strides  # 输入特征步幅列表self.hidden_dim = hidden_dim  # 隐藏层维度self.use_encoder_idx = use_encoder_idx  # 使用 Transformer 编码器的层索引self.num_encoder_layers = num_encoder_layers  # Transformer 编码器层数self.pe_temperature = pe_temperature  # 位置编码温度参数self.eval_spatial_size = eval_spatial_size  # 评估时的空间尺寸self.out_channels = [hidden_dim for _ in range(len(in_channels))]  # 输出通道数,统一为 hidden_dimself.out_strides = feat_strides  # 输出步幅,与输入相同encoder_layer = TransformerEncoderLayer_imporvedNorm(hidden_dim,  # 输入维度nhead=nhead,  # 注意力头数dim_feedforward=dim_feedforward,  # 前馈网络维度dropout=dropout,  # dropout 概率activation=enc_act  # 激活函数)self.encoder = nn.ModuleList([TransformerEncoder(copy.deepcopy(encoder_layer), num_encoder_layers)  # 深拷贝确保独立性for _ in range(len(use_encoder_idx))])

改进后的hybridencoder类需要注册,通过

@register()

实现。

在deim文件夹中的init.py文件中导入改进的模块。

from .hybrid_encoder_improved import HybridEncoder_improved

3 配置文件

新建一个配置文件,内容直接复制原配置文件,然后修改两个地方。

DEIM:backbone: HGNetv2encoder: HybridEncoder_improved ###decoder: DFINETransformerHybridEncoder_improved:  ###in_channels: [ 512, 1024 ]feat_strides: [ 16, 32 ]# intrahidden_dim: 128use_encoder_idx: [ 1 ]dim_feedforward: 512# crossexpansion: 0.34depth_mult: 0.5

修改完后,就可以尝试执行训练了,可能会报比如张量尺寸对不上的错误,因此还需要根据自己的情况多多调试。

这是一种简单改进的示例,更为复杂的改进可能需要不同的操作步骤。

http://www.xdnf.cn/news/473329.html

相关文章:

  • 前端学习:align-items 和 justify-content 概念和区别
  • 图片通过滑块小图切换大图放大镜效果显示
  • SDC命令详解:使用get_pins命令进行查询
  • Vue.js---避免无限递归循环 调度执行
  • Weblogic SSRF漏洞复现(CVE-2014-4210)【vulhub靶场】
  • 黑马Java基础笔记-11
  • 深度学习之用CelebA_Spoof数据集搭建一个活体检测-训练好的模型用MNN来推理
  • Turbo C++
  • 数据驱动下的具身智能进化范式
  • 专项智能练习(定义判断)
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.4.4)
  • threejs 大场景优化方案(代码层)
  • pycharm中qthread中的run函数debug不上的问题
  • 深度学习中的提示词优化:梯度下降全解析
  • 钉钉数据与金蝶云星空的无缝集成解决方案
  • mavgenerate 在 win11 下环境搭建注意问题
  • Kuberbetes-CA证书过期解决方案
  • linux系统中如何校准时间
  • windows、Ubuntu、Debian 添加静态路由
  • 从零开始学习PX4源码22(位置控制器---加速度部分理解)
  • MyBatis XML配置和入门使用
  • 论在中断中的标志变量使用volatile的重要性分析
  • 基于EtherCAT与ABP vNext 构建高可用、高性能的工业自动化平台
  • 双重差分模型学习笔记4(理论)
  • ip命令详解
  • HPC软件使用之ANSYS Fluent
  • Git-学习笔记(粗略版)
  • SpringBoot中的Lombok库
  • Python模块化编程
  • 俄罗斯方块算法