Hard Negative Mining
难负样本挖掘会找出模型最容易与正样本混淆的负样本,并将训练重点放在这些样本上,从而减少检测和搜索中的误报。
困难负样本挖掘是一种训练策略,它会找出模型最容易出错的负样本,并集中学习这些样本。负样本不属于目标类别;困难负样本则是模型仍然将其评分为正样本的样本,例如被检测器框成物体的背景区域,或被嵌入模型放在查询附近的不相关图像。大多数负样本都很容易,一旦模型掌握了这些样本,它们几乎不再提供学习信号;因此,选出困难样本能让决策边界更加清晰,并减少假阳性。
困难负样本挖掘的工作原理#
什么算困难样本取决于任务:
- 在目标检测中,如果检测器将背景区域判为物体,该区域就是困难样本。
- 在分类中,困难负样本是指被错误分类、但对目标类别却有高置信度的样本。
- 在检索和推荐系统中,困难负样本是与查询无关、但排名很靠近查询的项目;得分较高的负样本对梯度影响最大。
- 在度量学习中,困难负样本是指比匹配正样本更靠近锚点的负样本,三元组间隔损失会对这种情况进行惩罚。
困难样本挖掘可以离线或在线进行。离线挖掘会让训练好的模型处理大量仅含负样本的数据,收集模型产生的假阳性,将其加入训练集,然后重新训练。早期的滑动窗口行人检测器就是这样训练的:扫描无人图像,找出误报并据此重新训练。在线挖掘则会在每个训练批次中选择困难样本。SSD会按照分类损失对负样本默认框排序,只保留损失最高的部分,每个正样本最多对应 3 个负样本;在线困难样本挖掘(OHEM)则将同一思路应用于两阶段检测器的区域候选。SSD 的筛选只需几行代码:
import torch
import torch.nn.functional as F
torch.manual_seed(0)
# Simulated objectness logits for 8,400 candidate boxes: 20 cover an object, the rest are background
logits = torch.randn(8400) - 3
labels = torch.zeros(8400)
labels[:20] = 1
loss = F.binary_cross_entropy_with_logits(logits, labels, reduction="none")
# Keep every positive plus only the highest-loss negatives, at most 3 per positive
positives = labels == 1
negative_loss = loss.masked_fill(positives, 0)
hard_negatives = negative_loss.topk(3 * int(positives.sum())).indices
kept = torch.cat([positives.nonzero().squeeze(1), hard_negatives])
print(f"boxes in the loss: {len(kept)} of {len(loss)}")
print(f"mean negative loss: all {loss[~positives].mean():.3f}, mined {loss[hard_negatives].mean():.3f}")损失计算只保留 8,400 个框中的 80 个:20 个正样本,以及模型最容易判为物体的 60 个负样本。这 60 个挖掘出的负样本平均损失为 0.648,而全部 8,380 个负样本的平均损失为 0.075,因此梯度会集中在模型实际容易混淆的背景上。
困难负样本挖掘与相关技术的比较#
- 负采样:从全部负样本中选取一个可处理的子集,通常随机抽取。困难负样本挖掘则会挑出最容易造成混淆的样本。
- 焦点损失:在损失计算中保留所有样本,但降低分类正确样本的权重。这使 RetinaNet 等单阶段检测器无需显式采样,也能在所有候选框上训练。
- 主动学习:选择不确定的无标签样本供人工标注,其中也包括可能的正样本。困难负样本挖掘针对的则是已经确认的负样本。
- 类别再平衡:通过下采样和提高权重来纠正类别频率不均衡。常见的负样本类别不一定就是困难类别。
- 数据增强:生成现有样本的变体,但无法引入数据集中从未出现过、会造成混淆的物体。
实际应用#
- 仓库安全检测:叉车检测器若反复将托盘搬运车、货架反光和剪叉式升降机误判为叉车,就会因频繁误报而失去操作人员的信任。将这些场景作为负样本图像收集起来并重新训练,可以教会检测器区分叉车与类似设备的特征。
- 视觉商品搜索:搜索某款黑色跑鞋时,如果相似但属于其他产品系列的鞋排名过高,这些商品就成了困难负样本。使用这些商品进行训练,例如将它们作为孪生网络锚点-正样本-负样本三元组中的负样本,可以教会嵌入模型保留鞋底形状、Logo 位置和材质等细微差异。
离线挖掘工作流#
每一轮离线挖掘都会运行当前模型、确认模型标记的内容,并将确认的样本纳入训练:
审查步骤很重要,因为“假阳性”往往是真实物体,只是标注人员漏掉了它;若将其添加为负样本,就会教模型抑制真实检测结果。Ultralytics YOLO 会将缺少标签文件或标签文件为空的图像视为背景图像,因此其中每个锚点都会获得零目标分数,任何高置信度预测都会受到惩罚。这样一来,将挖掘出的负样本加入 YOLO26 数据集时,只需复制图像而不添加标签。进展表现为在召回率保持不变时精确率提高,并在完整测试集和专门的困难负样本子集上进行跟踪。
只使用最困难的负样本进行训练可能适得其反。在 FaceNet 的人脸嵌入训练中,过早选取最困难的负样本可能会导致模型塌缩,将每张人脸映射到同一个点。因此,作者使用半困难负样本训练:这类样本比正样本离锚点更远,但仍处于三元组间隔之内。










