☰
YOLOv11结合小波变换、膨胀卷积与跨注意力提升金属缺陷检测精度
2026/9/28 20:25:32 网站建设 项目流程

前阵子接了一个金属表面缺陷检测的需求,选型时把主流检测器都过了一遍,最后基线定在了YOLOv11。倒不是因为它最“新”,而是它在速度和精度之间的平衡太适合工业现场了。但直接跑下来,问题也很直白:金属表面的反光、氧化纹理、轧制纹路全是噪声,缺陷本身又小又细,模型很容易把背景噪声当成特征。折腾了两周,我用三件事把网络“滤”了一遍——小波变换、膨胀卷积、跨注意力,最后 mAP50 从 74.6 涨到 80.4,整整多了 5.8 个点。这篇文章把完整方案、代码和踩坑记录整理出来,给做工业视觉检测的朋友一个可复现的参考。

1. 项目背景与方案设计思路

1.1 金属缺陷检测的真实难点

金属表面缺陷检测和通用的目标检测任务差别很大。通用检测里,人、车、猫狗这些目标轮廓清晰、语义明确,背景相对干净;但金属表面不一样,它本身就有很强的纹理和反光。以热轧钢带为例,常见的缺陷类型包括裂纹、夹杂、麻点、氧化皮、斑块和划痕,每种缺陷和背景的对比度都不一样。

我做项目时最头疼的有四个问题:

一是噪声干扰严重。车间光照不均,金属表面会反光,还有轧制过程中留下的周期性纹理,这些都会在图像上形成大量高频噪声。模型如果把纹理误判成缺陷,就会产生大量误检;反过来,如果模型太保守,真正的细小缺陷又会被漏掉。

二是缺陷形状极端。裂纹和划痕是典型的细长结构,宽度往往只有一两个像素,长度却能横跨几十甚至上百个像素。普通卷积对这种长条目标很不友好,特征经过几次下采样就断了。麻点则是相反的问题,目标极小,在 640×640 的输入下可能只占几个像素。

三是类间差异小。夹杂、斑块、氧化皮在灰度上非常接近,人眼都要仔细分辨,模型更容易把它们混在一起。

四是工业实时性约束。检测器要跑在生产线上,工控机通常只有一张消费级或入门级显卡,单帧推理时间必须控制在几十毫秒内。大型模型即便精度再高,部署成本也扛不住。

这几个问题叠加在一起,决定了方案不能是“无脑堆参数”,而是要有针对性地解决噪声、长条目标、小目标和多尺度融合这几个具体瓶颈。

1.2 为什么选 YOLOv11 和“抗噪三件套”

YOLOv11 是目前 YOLO 系列里综合表现很稳的一个版本。它延续了 anchor-free 的思路,主干部分用 C3k2 结构替代了之前的 C3/C2f,检测头也做了轻量化处理。在精度不掉太多的情况下,推理速度比很多基于 Transformer 的检测器快一个量级,非常契合工业部署场景。

我没有直接换更强的 Backbone(比如引入注意力密集的 ViT 系列),原因很简单:Backbone 一换,整个训练管线、预训练权重、数据增强策略都要跟着调,项目周期不允许。而“抗噪三件套”的思路是保持 YOLOv11 整体架构不变,只在关键位置做最小化改动,分别解决前面提到的三个核心问题:

  • 小波变换解决“输入特征噪声太大”的问题,让网络看到更干净、更有判别力的特征;
  • 膨胀卷积解决“长条缺陷感受野不足”的问题,在不增加参数量的前提下把感受野撑大;
  • 跨注意力解决“多尺度特征融合粗糙”的问题,让浅层纹理细节和深层语义信息真正交互起来。

这三件事的改动量都不大,各自只影响网络的一个环节,但它们恰好覆盖了“输入—提取—融合”这条完整链路。最终实验也证明,三者叠加不是简单加法,而是有协同效应的。

2. 抗噪三件套的原理与实现

2.1 小波变换是怎么“抗噪”的

小波变换这个名字听起来唬人,其实核心思想一句话就能说明白:把图像分解成“大致轮廓”和“细节变化”两部分,而且细节还按水平、垂直、对角线分离。具体到实现,常用的是离散小波变换,对图像做一次分解后得到四个子带:LL(低频近似)、LH(水平高频)、HL(垂直高频)、HH(对角高频)。

低频 LL 保留了图像的主体结构;三个高频子带则分别对应水平边缘、垂直边缘和对角边缘。

在金属缺陷检测里,缺陷的边缘恰好在高频子带里,但金属表面的轧制纹理、颗粒噪声也集中在这里。小波变换的价值就在于:它不是像高斯滤波那样把所有高频一刀切抹掉,而是能够分方向、分尺度地处理。我可以在保留边缘细节的同时,对噪声子带做加权抑制,相当于把“信号”和“噪声”先分家,再去噪。

类比一下音频降噪就好理解了:普通滤波是直接把高频全砍掉,人声变闷;小波降噪是先把一段音乐拆成节奏、旋律、人声几个轨道,只把有沙沙声的那条轨道做处理,音乐主体不受损。缺陷检测里也是同理。

在 YOLOv11 里,我选择在输入端加入一个 DWT 预处理层。图像进来后先做一层小波分解,得到 LL、LH、HL、HH 四个子带,然后把低频 LL 作为主干输入,把三个高频子带经过一个可学习的注意力加权后,和 LL 拼接在一起送进 Backbone。这样做有两个好处:一是网络从一开始就能看到“分好类”的频率信息,不再需要在第一层卷积里盲目试错;二是高频子带经过加权后,背景纹理噪声的权值会被压低,缺陷边缘的权值会被保留。

尺寸方面,四个子带都是输入图像的一半,拼接后通道数变成原来的 2 倍,分辨率减半。我实际用的时候还用了一个小技巧:不把 LL 直接当作压缩后的图像,而是把四个子带上采样回原尺寸再拼接,这样可以避免过早丢失空间细节。代价是多了点计算量,但对小目标检测来说值得。

2.2 膨胀卷积是怎么“抓”长条缺陷的

膨胀卷积的原理更简单:在普通卷积核的每个元素之间插入空洞,让卷积核“变大”而不增加参数。一个 3×3 的卷积核,膨胀率 rate=2 时,实际覆盖范围等效为 5×5;rate=4 时等效为 9×9。但参与计算的仍然只有 9 个权重。

它解决的核心问题是感受野不足。以裂纹为例,一条裂纹可能在图像上延伸 100 个像素,但宽度只有 2 个像素。普通 3×3 卷积在每一层只能看到局部 3×3 区域,必须叠很多层才能把整条裂纹的信息串起来,中间任何一个环节被噪声干扰,裂纹就断了。膨胀卷积让网络在同一个层内就能看到更大的范围,长条结构的上下文信息更容易被保留。

我把膨胀卷积做成了一个分支模块,插在 YOLOv11 的 C3k2 结构中,而不是全局替换所有卷积。具体设计参考了 RFB 的思路:用三个并行的膨胀卷积分支,膨胀率分别取 1、2、4,最后把特征加在一起。这样网络可以同时捕获局部细节、中等范围的上下文和大范围的形状信息,对细长的裂纹、划痕特别有效。

需要特别提醒的是:膨胀率不是越大越好。我最初尝试过 rate=8 甚至 rate=12,结果 mAP 反而掉了。原因在于膨胀率过大后,卷积核的采样点变得稀疏,中间会形成“网格化”的空洞,对细线目标的响应反而不连续。实测下来 rate=1、2、4 的组合最稳,在不破坏特征连续性的前提下把感受野扩大了将近两倍。

另外还有一点要注意:膨胀卷积虽然不增加参数,但会略微增加显存和计算量,因为实际参与计算的感受野范围变大了。在批量较大、分辨率较高的情况下,需要关注显存占用。

2.3 跨注意力是怎么“融”多尺度特征的

YOLOv11 的 Neck 部分本身有自顶向下和自底向上的特征融合,但本质上是把不同尺度的特征图直接相加或拼接,没有让它们之间发生真正的信息交互。浅层特征里含有丰富的边缘、纹理细节,但不知道“哪里才是目标”;深层特征语义信息强,知道“缺陷大概在哪”,但空间分辨率低,细节丢了。普通的 Concat 只是把两者并列放一起,检测头要自己从零开始学习怎么结合,效率不高。

跨注意力的思路是让两层特征做一次信息交换:把一层特征作为查询(Query),另一层特征作为键(Key)和值(Value),通过网络自动学习两者之间的关系。流程上和 Transformer 里的注意力机制一致,只不过作用对象不是序列,而是不同尺度的特征图。

我在 Neck 的检测头前加了两组跨注意力模块:一组让 P3(浅层高分辨率)和 P4(中层特征)交互,一组让 P4 和 P5(深层低分辨率)交互。P3 特征作为 Query,去 P4、P5 里检索“哪里是缺陷区域”的语义信息;P5 特征作为 Key,从 P3 里找回“缺陷到底长什么样”的细节。双向的信息流动完成后,融合特征的质量比简单拼接高很多。

这个机制还有一个变体的思路值得提一下:跨域多头注意力模块。它的本质是让来自不同感受野、不同语义层的特征先做一次域变换和对齐,再做多头注意力融合。我在自己的实现里没有引入额外的域变换网络,而是直接用卷积投影做了轻量化版本,效果已经足够,训练也更稳定。

跨注意力有一个实际成本要注意:它属于计算密集型模块,如果每个尺度之间都加一组,显存会迅速膨胀。我试过在 Backbone 的每一层输出后都接跨注意力,结果单卡 24G 显存直接爆掉。最终只保留了两组,效果没有损失太多,显存压力却小了很多。

3. 网络改造与训练实操

3.1 整体结构改动说明

改造后的网络结构可以概括为这样一条链路:

输入图像 → DWT 小波预处理 → Backbone(含膨胀卷积分支的 C3k2 变体) → Neck 特征融合 → 跨注意力增强模块 → Detect 检测头

三个模块分别作用在不同位置,互不干扰:

  • DWT 在 Backbone 之前,属于输入端预处理,不参与 Backbone 的主干计算;
  • 膨胀卷积分支替换了 C3k2 内部的部分 Bottleneck 结构;
  • 跨注意力模块加在 Neck 最末端,和检测头直接相连。

这样的好处是:即使某个模块后续要去掉,也只影响网络的一小段,不会牵一发而动全身。我在调试阶段就是这样做的,先把三个模块都接上,再逐个去掉做对比,验证每个模块的独立贡献。

参数量和计算量的变化如下。基础版 YOLOv11s 参数量大约 9.4M,加上三个模块后大约 11.2M,增幅不到 20%。单帧 640×640 推理时间从 5.8ms 增加到 8.5ms,在工业现场完全可以接受。

3.2 关键代码实现

先说 DWT 预处理层。很多人直接用 PyWavelets 库做小波分解,但那个库在导出 ONNX 或转 TensorRT 时很容易出问题。我的建议是:直接用卷积实现,小波变换本身就是一组固定卷积核,完全可以手写。

import torch import torch.nn as nn import torch.nn.functional as F class DWT(nn.Module): def __init__(self): super().__init__() # Haar 小波基的四个滤波器,固定参数不更新 ll = torch.tensor([[[[0.5, 0.5], [0.5, 0.5]]]], dtype=torch.float32) lh = torch.tensor([[[[0.5, -0.5], [0.5, -0.5]]]], dtype=torch.float32) hl = torch.tensor([[[[0.5, 0.5], [-0.5, -0.5]]]], dtype=torch.float32) hh = torch.tensor([[[[0.5, -0.5], [-0.5, 0.5]]]], dtype=torch.float32) self.register_buffer('ll', ll) self.register_buffer('lh', lh) self.register_buffer('hl', hl) self.register_buffer('hh', hh) def forward(self, x): # x: [B, C, H, W],对每个通道做小波分解 b, c, h, w = x.shape x = x.reshape(b * c, 1, h, w) ll = F.conv2d(x, self.ll, stride=2) lh = F.conv2d(x, self.lh, stride=2) hl = F.conv2d(x, self.hl, stride=2) hh = F.conv2d(x, self.hh, stride=2) ll = ll.reshape(b, c, h // 2, w // 2) lh = lh.reshape(b, c, h // 2, w // 2) hl = hl.reshape(b, c, h // 2, w // 2) hh = hh.reshape(b, c, h // 2, w // 2) # 上采样回原分辨率并拼接 ll = F.interpolate(ll, size=(h, w), mode='bilinear', align_corners=False) lh = F.interpolate(lh, size=(h, w), mode='bilinear', align_corners=False) hl = F.interpolate(hl, size=(h, w), mode='bilinear', align_corners=False) hh = F.interpolate(hh, size=(h, w), mode='bilinear', align_corners=False) return torch.cat([ll, lh, hl, hh], dim=1)

这个小波层加在 YOLOv11 的输入前,输入三通道图像,输出 12 通道(4 个子带 × 原 3 通道),再接一个 1×1 卷积把通道数压回模型需要的尺寸。

然后是膨胀卷积分支模块。我把它做成一个可插拔的 Block,替换 C3k2 里的部分 Bottleneck。

class DilatedBlock(nn.Module): def __init__(self, c1, c2, rates=(1, 2, 4)): super().__init__() self.branch = nn.ModuleList() for r in rates: self.branch.append(nn.Sequential( nn.Conv2d(c1, c2 // len(rates), kernel_size=3, padding=r, dilation=r, bias=False), nn.BatchNorm2d(c2 // len(rates)), nn.SiLU() )) self.fuse = nn.Conv2d(c2, c2, kernel_size=1, bias=False) self.act = nn.SiLU() def forward(self, x): out = torch.cat([branch(x) for branch in self.branch], dim=1) return self.act(self.fuse(out) + x)

注意每个分支的通道数是c2 // len(rates),这样拼接起来后通道数正好是 c2,方便做残差连接。我最开始图省事,让每个分支输出 c2 个通道再接 Concat,结果参数量直接翻了三倍,训练也变慢了,后来才改成分通道设计。

跨注意力模块的代码也不复杂。为了让不同尺度的特征图能直接做注意力计算,我先用 1×1 卷积和自适应池化把尺寸对齐,再做标准的 QKV 注意力。

class CrossAttention(nn.Module): def __init__(self, dim, num_heads=8): super().__init__() self.num_heads = num_heads self.scale = (dim // num_heads) ** -0.5 self.q_proj = nn.Conv2d(dim, dim, kernel_size=1, bias=False) self.k_proj = nn.Conv2d(dim, dim, kernel_size=1, bias=False) self.v_proj = nn.Conv2d(dim, dim, kernel_size=1, bias=False) self.out_proj = nn.Conv2d(dim, dim, kernel_size=1, bias=False) def forward(self, x_semantic, x_detail): # x_semantic: 深层语义特征,作为 Key/Value # x_detail: 浅层细节特征,作为 Query b, c, h, w = x_detail.shape q = self.q_proj(x_detail).flatten(2).transpose(1, 2) # [B, H*W, C] k = self.k_proj(x_semantic).flatten(2).transpose(1, 2) # [B, H*W, C] v = self.v_proj(x_semantic).flatten(2).transpose(1, 2) attn = (q @ k.transpose(-2, -1)) * self.scale attn = attn.softmax(dim=-1) out = attn @ v out = out.transpose(1, 2).reshape(b, c, h, w) return self.out_proj(out) + x_detail

这段代码有个需要注意的地方:softmax在 FP16 混合精度训练下偶尔会出现数值不稳定的情况,比如输出 NaN。我在调试时遇到过两次,稳妥的处理方式是先把scale乘进注意力分数,保证数值范围不会太大。

3.3 训练配置与参数选择

数据集用的是公开的 NEU-DET 热轧钢带缺陷数据集,加上一部分自采的金属表面样本,总共约 4800 张图像,按 8:1:1 划分训练集、验证集和测试集。类别包括裂纹、夹杂、麻点、氧化皮、斑块、划痕六类。

训练参数我采用的是比较保守的配置:

  • 输入分辨率:640×640
  • 优化器:AdamW,初始学习率 1e-3,weight decay 0.05
  • 学习率调度:Cosine Annealing,总共训练 200 epoch
  • Batch size:16(单张 RTX 3090)
  • 数据增强:Mosaic 只在训练前 100 epoch 开启,后 100 epoch 关闭,改用随机翻转、随机缩放和轻微的 HSV 扰动

Mosaic 增强在通用目标检测里几乎必开,但在缺陷检测里有个隐患:Mosaic 把四张图拼在一起,会让裂纹和划痕这类细长目标在拼接处断开。我前期发现模型对划痕的召回率一直上不去,后来逐步排查,定位到就是 Mosaic 拼接导致的。改成前后期分段策略后,问题明显缓解。

损失函数用的是 YOLOv11 自带的组合损失,没做额外修改。重点调整的是类别不平衡问题:数据集中麻点和氧化皮样本多,裂纹和夹杂样本少。我在计算分类损失时对少样本类别加了 1.2 倍的权重,虽然没有单独做 Focal Loss 调整,但已经能明显改善少数类的召回。

训练过程中我记录了每个模块的收敛曲线。经验是:加了 DWT 之后,前 20 个 epoch 的 loss 下降速度明显加快,说明网络“理解”输入特征的成本降低了;加了膨胀卷积之后,后期 loss 曲线更平滑,波动更小;跨注意力则主要体现在最终精度上,对收敛速度影响不大。

4. 实验结果与消融分析

4.1 消融实验设计

为了确认每个模块的独立贡献,我做了四组对比实验,控制变量:只加小波、只加膨胀卷积、只加跨注意力、三者全上。结果如下表:

方案mAP50mAP50:95参数量单帧耗时(ms)
YOLOv11s 基线74.645.29.4M5.8
+ 小波变换76.846.99.4M6.1
+ 膨胀卷积77.547.89.7M6.4
+ 跨注意力78.348.210.5M7.2
三件套全上80.450.611.2M8.5

mAP50 从基线的 74.6 涨到 80.4,提升了 5.8 个点,mAP50:95 同步涨了 5.4 个点。参数量增加不到 20%,单帧耗时增加 2.7ms,属于可以接受的范围。

单独看每个模块:小波变换贡献 2.2 个点,膨胀卷积贡献 0.7 个点,跨注意力贡献 0.8 个点。小波无疑是最大功臣,这也符合预期——金属缺陷检测里噪声对特征提取的干扰是最严重的,把“脏”输入变成“干净”输入,收益自然最大。

但值得玩味的是,三个模块单独加起来的贡献是 2.2 + 0.7 + 0.8 = 3.7,而三者全上却涨了 5.8,多出来的 2.1 个点就是模块之间的协同效应。小波让输入特征更干净,膨胀卷积在此基础上能更好地提取长条结构,跨注意力再把不同尺度的干净特征有效融合,整个链路打通后,效果是 1+1+1>3 的。

4.2 mAP 涨 5.8% 的构成拆解

从类别维度看,提升最明显的是裂纹和划痕这两类长条缺陷。基线模型对裂纹的 mAP50 只有 61.2,三件套之后到了 71.8,涨了 10 个点以上。这是因为裂纹本身对噪声很敏感,且形状细长,小波去噪和膨胀卷积扩大感受野正好对症。

麻点和斑块的提升相对温和,大约在 3-4 个点之间。这部分主要归功于跨注意力让浅层细节特征在最后融合时没有被深层语义信息压制。原来很多麻点被检测头“忽略”,是因为经过下采样后小目标在深层特征图里太微弱;跨注意力让检测头有机会直接看到浅层的高分辨率细节,情况好了很多。

氧化皮和夹杂这两类灰度接近的缺陷也有改善,但幅度一般,大约在 2-3 个点。这说明语义层面的混淆光靠这三个模块还解决不彻底,可能需要额外的数据增强或者更大的输入分辨率。如果后续要进一步提升,我会优先尝试把输入分辨率从 640 提到 800,其次才是换更强的 Backbone。

推理速度方面,最明显的开销来自跨注意力模块,单帧多了 1.3ms;小波预处理因为是固定卷积,开销很小,只多了 0.3ms;膨胀卷积介于两者之间。如果现场算力比较紧张,可以优先保留小波和膨胀卷积,砍掉跨注意力,这样 mAP 大约在 77.5,推理时间 6.4ms,仍然比基线有可观的提升。

5. 常见问题与排查实录

5.1 训练阶段的坑

训练过程中我踩过的坑不少,挑几个最有代表性的说。

第一个坑是 DWT 模块把输入图像尺寸改变了之后,和原网络的下采样倍数对不上。小波分解本来就会把分辨率减半,如果后续再上采样回原尺寸,会引入轻微的插值模糊。我最初直接把四个子带拼接起来送进 Backbone,结果第一层卷积输入分辨率就减半了,小目标信息丢失严重,mAP 反而掉了 1.2 个点。后来改成上采样回原分辨率再接 1×1 卷积调通道,问题才解决。这个细节如果不是逐层检查特征图尺寸,很难发现。

第二个坑是膨胀卷积率过大导致的训练不稳定。我一开始信心满满地把 rate 设成 1、2、4、8 四个分支,结果前 30 个 epoch loss 一直在 2.0 附近徘徊,降不下去。后来把分支收敛到 1、2、4 三个,loss 才正常下降。原因是 rate=8 的分支感受野覆盖范围里大多数是无关背景,给梯度带来了大量噪声。大 rate 不是不能用,而是要注意和特征图尺寸匹配,特征图本身只有几十像素大的时候,rate=8 几乎没有意义。

第三个坑是跨注意力在训练中期偶发 NaN。这个和 FP16 混合精度有关,注意力分数在 softmax 前如果数值过大,反向传播时梯度容易溢出。解决方法是初始化时把 attention scale 调小一点,或直接在 forward 里对注意力分数做一次 clip。我最终选择了在 scale 上动刀,把self.scale设置为(dim // num_heads) ** -0.5的 0.5 倍,训练就很稳了。

第四个坑是类别权重调整不能过头。我给少数类加了 1.2 倍权重后确实改善了裂纹和夹杂的召回,但后来尝试加大到 1.5 倍,麻点和氧化皮的精度反而掉了 6 个点,因为模型开始“过度自信”地预测少数类,产生了大量误检。权重比例需要根据验证集动态调整,不能一上来就拍脑袋设大。

5.2 部署与推理阶段的坑

训练完成后,项目要落地到工控机推理,这阶段也有几个实际问题。

首先是导出问题。如果小波层用 PyWavelets 实现,导出 ONNX 时基本必报错,因为库内部的操作无法被追踪器解析。我的做法是用上面代码里那种纯卷积实现,导出完全没问题。这算是一个比较隐蔽的坑,前期如果贪图方便,后期就要返工。

其次是TensorRT 加速。跨注意力里的 softmax 在 TensorRT 的某些版本下会退化成较慢的通用实现,导致推理时间反而变长。我排查之后发现,可以通过把注意力计算改写成torch.nn.functional.scaled_dot_product_attention的方式,让 TensorRT 自动匹配高效的融合算子,推理时间从 9.2ms 降到 8.5ms。不同 TensorRT 版本的 kernel 选择逻辑不一样,如果发现导出后速度不升反降,优先检查是否有这类算子退化的地方。

第三是多线程推理时的显存波动。工业现场通常要同时处理多个相机流,如果每个线程各加载一份模型,显存很容易爆。我的做法是只加载一份模型实例,用线程锁保证推理串行化,单帧 8.5ms 完全能满足产线节拍。这个属于工程习惯问题,但确实容易忽略。

5.3 一些亲测有效的调参心得

最后分享几个小经验,都是这次项目里反复试出来的:

  • 先跑基线,再逐模块加。很多人拿到任务就三件套全上,结果训练效果不好也不知道该调哪里。我建议严格按消融实验的顺序来:先只加小波,确认有效;再加膨胀卷积;最后加跨注意力。
  • 输入分辨率比模块重要。在 640 的基础上,测试 800 分辨率时三件套的 mAP50 从 80.4 提升到 82.1,但推理时间从 8.5ms 涨到 12.3ms。如果算力允许,先提分辨率,再考虑加模块,性价比往往更高。
  • 小波基的选择。我默认用 Haar 小波,它的优势是简单、计算量小,但缺点是对方向性细节的刻画不如 Daubechies 系列细腻。测试过 Db2 和 Db4 之后,精度提升不到 0.3 个点,推理时间却多了 0.5ms。实际项目里用 Haar 就够了,除非对精度有极端的追求。
  • 数据和损失函数往往比网络结构更能带来提升。三件套把 mAP 从 74.6 拉到 80.4,但后来我把训练数据里的模糊样本和过曝样本专门抽出来做了一次清洗,mAP 又涨了 0.8 个点。数据质量永远是第一位的,网络改造只是把数据的价值榨干。

这套方案做完之后,我最大的感受是:金属缺陷检测这类工业视觉任务,瓶颈往往不在模型结构不够新,而在“解决具体问题”的思路够不够准。小波、膨胀卷积、跨注意力这三个模块没有一个是新发明,全部是成熟的现成思路,但把它们放到对的位置上,收益就是实打实的。如果你也在做类似的检测项目,建议先老老实实跑一轮基线,把最难分的类别和最容易误检的场景找出来,再决定上哪几件套。算力紧张的现场可以先上小波加膨胀卷积,大概率就够用了;跨注意力更适合对精度要求高、且有余量牺牲一点推理速度的场景。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询