
YOLO 中引入 MoE(Mixture of Experts)后(eg:yolo-master),漏检下降但误检(FP)升高 是非常常见的问题。因为 MoE 本质上增加了模型容量和表达能力,如果路由器(Gate)没有学好,很容易产生「过拟合局部模式」和「专家幻觉」。

建议从以下几个方向排查。
文章目录
- [1. 先确认误检发生在哪些类别](#1. 先确认误检发生在哪些类别)
- [2. 看 Gate 是否塌缩(最常见)](#2. 看 Gate 是否塌缩(最常见))
- [3. 增加 Load Balance Loss](#3. 增加 Load Balance Loss)
- [4. MoE 放置位置不对](#4. MoE 放置位置不对)
- [5. Expert 数量太多](#5. Expert 数量太多)
- [6. Top-k 太大](#6. Top-k 太大)
- [7. 分类分支过强](#7. 分类分支过强)
- [8. 调高推理阈值](#8. 调高推理阈值)
- [9. 增加负样本](#9. 增加负样本)
- [10. 检查 NMS](#10. 检查 NMS)
- 经验总结
1. 先确认误检发生在哪些类别

不要只看 mAP。
重点看:
- 哪个类别 FP 最多
- FP 出现在什么场景
- FP 的置信度分布
例如:
| 类别 | TP | FP |
|---|---|---|
| person | 10000 | 500 |
| bicycle | 1000 | 2000 |
如果发现:
text
某几个类别 FP 爆炸
通常是:
- 类别特征被某个 Expert 过拟合
而不是整个网络问题。
建议直接输出:
python
confusion_matrix.png
和
python
PR_curve.png
看看哪些类别出了问题。
2. 看 Gate 是否塌缩(最常见)

很多 YOLO-MoE 实现有个问题:
text
所有样本都走同一个 Expert
例如:
text
Expert0 : 82%
Expert1 : 10%
Expert2 : 5%
Expert3 : 3%
这叫:
text
Expert Collapse
此时:
- 实际上只有一个 Expert 在工作
- 其它 Expert 没学到东西
最终:
text
训练集很好
验证集误检很多
统计一下:
python
gate.argmax(1)
看看每个 expert 被选中的比例。
理想情况:
text
25%
25%
25%
25%
或者:
text
30%
20%
28%
22%
都可以。
3. 增加 Load Balance Loss

Google Switch Transformer 的经典方案:
L = L d e t + λ L b a l a n c e L = L_{det} + λL_{balance} L=Ldet+λLbalance
例如:
python
lambda_balance = 0.01
或者:
python
0.05
作用:
text
让各个 Expert 都被使用
很多 YOLO-MoE Repo 默认:
python
lambda = 0
或者太小。
这是误检增加的常见原因。
4. MoE 放置位置不对

很多人直接把:
text
C2f
Bottleneck
替换成:
text
MoE Block
但实际上:
Backbone 早期层
例如:
text
P1
P2
这里放 MoE 很危险。
因为:
text
边缘
纹理
角点
本来应该共享。
结果专家学出不同风格:
text
Expert0 学边缘
Expert1 学纹理
Expert2 学噪声
误检会上升。
经验:
MoE 更适合:
text
Backbone 后部
Neck
Head 前
例如:
text
P4
P5
而不是:
text
P1
P2
5. Expert 数量太多

例如:
yaml
num_experts: 8
但数据集:
text
5000张
这几乎必然过拟合。
经验:
| 数据规模 | Expert |
|---|---|
| <10k | 2~4 |
| 10k~100k | 4~8 |
| >100k | 8~16 |
如果 CrowdHuman:
text
15000张
建议:
yaml
num_experts=2
先试。
6. Top-k 太大

很多实现:
python
topk = 2
甚至:
python
topk = 4
会导致:
text
多个 Expert 输出叠加
容易出现:
text
背景响应增强
最终:
text
FP增加
建议先试:
python
topk = 1
即:
text
Switch Transformer风格
通常误检会明显下降。
7. 分类分支过强

YOLO 检测头:
text
Cls
Obj
Box
MoE 常常提升:
text
Cls score
但:
text
Obj score
没有同步提升。
结果:
text
背景区域
↓
分类分数很高
↓
误检
检查:
python
cls_score
obj_score
分布。
很多 FP 会发现:
text
cls=0.98
obj=0.15
这种典型是假阳性。
8. 调高推理阈值

先验证是不是「高分误检」。
例如:
bash
conf=0.25
改:
bash
conf=0.4
或者:
bash
conf=0.5
观察:
text
FP下降多少
Recall下降多少
如果:
text
FP大幅下降
Recall几乎不变
说明:
text
MoE产生大量低质量框
不是定位能力问题。
9. 增加负样本

MoE 特别容易:
text
记住背景纹理
例如:
- 路面
- 树叶
- 阴影
- 反光
被误认为目标。
可尝试:Hard Negative Mining
把误检区域裁出来:
text
false positive
加入训练。
很多时候:
text
误检直接下降 20~50%
10. 检查 NMS

有些 MoE Head 会产生:
text
多个专家输出多个相似框
导致:
text
NMS后仍残留
可以尝试:
python
iou_thres
从:
python
0.7
改:
python
0.5
或者:
python
0.45
看看 FP 是否明显下降。
经验总结

如果你的现象是:
text
Baseline:
P=0.95
R=0.77
MoE:
P=0.92
R=0.80
即:
text
召回上升
精度下降
优先排查顺序:
- Gate 是否塌缩(最重要)
- Expert 数量是否过多
- Top-k 是否 >1
- 是否缺少 Load Balance Loss
- MoE 是否放在 Backbone 前层
- Hard Negative Mining
实际项目里,我见过超过一半的 YOLO-MoE 误检问题,最终都能归因到 Gate 塌缩 + Expert 过拟合 这两个原因。
