Fast RCNN 中的 Hard Negative Mining

本文深入解析FastRCNN中硬负例挖掘的原理与策略,探讨如何通过筛选难以正确分类的负样本提高目标检测算法的性能。文章详细解释了正负样本比例的选择依据,以及IoU在不同区间内负样本的分类难度,并介绍了传统硬例挖掘的流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-w980

Fast RCNN 中将与 groud truth 的 IoU 在 [0.1, 0.5) 之间标记为负例, [0, 0.1) 的 example 用于 hard negative mining. 在训练时一般输入为N=2张图片, 选择 128 个 RoI, 即每张图片 64 个 RoI. 每张图片, 按照1:3的比例来抽取的 RoI 的话, 要在负例中抽取 48 个, Fast RCNN 采用 random sampling 策略.

hard negative example

首先我们看看 hard negative example 是怎么定义?

negative,即负样本,hard 说明是难以正确分类的样本,也就是说在对负样本分类时候,loss比较大(label与prediction相差较大)的那些样本,也可以说是容易将负样本看成正样本的那些样本;

然后我们看看Fast RCNN 中的一些概念

对于目标检测, 我们会事先标记 ground truth,然后再算法中会生成一系列 proposal,这些 proposal有跟 ground truth重合的也有没重合的,那么 IoU 超过一定阈值(通常0.5)的则认定为是正样本,以下的则是负样本, 然后扔进网络中训练。 然而,这也许会出现一个问题那就是正样本的数量远远小于负样本,这样训练出来的分类器的效果总是有限的,会出现许多 false negative, 即预测为负例的正样本

一般来说, 负样本远多于正样本, 如 99% 的负样本, 那么算法不需要训练直接输出为负例, 准确率也会有 99%, 那么正负样本不均衡时, 预测偏向于样本多的一方, 对于目标检测而言, 负例多, 所以被预测为 false negative(即预测为负例的正样本) 可能性比较大.

我们为了避免这样一种情况, 需要使用策略使得正负样本尽量的均衡一点, Fast RCNN 采用的是随机抽样, 使得正负样本的比例为 1:3, 为何是1:3, 而不是1:1呢? 可能是正样本太少了, 如果 1:1 的话, 一张图片处理的 ROI 就太少了, 不能充分的利用 Roi Pooling 前一层的共享计算, 训练的效率就太低了, 但是负例比例也不能太高了, 否则算法会出现上面所说的 false negative 太多的现象, 选择 1:3 这个比例是算法在性能和效率上的一个折中考虑, 同时 OHEM(online hard example mining)一文中也提到负例比例设的太大, Fast RCNN 的 mAP将有很大的下降.

一些思考

Fast RCNN中选用 IoU < 0.1 作为hard negative的话,这样的 IoU 值对应的负样本一般不会被误判。我的理解下,不是应该把那些IoU值较高但是标记为负样本的样本更容易被误判吗?所以 hard negative mining 应该从这些样本里面(比如在Fast Rcnn中 IoU 在 [0.1, 0.5) 定义的负样本) 挑选不是更加合理吗?

我们可以先验的认为, 如果 Roi 里没有物体,全是背景,这时候分类器很容易正确分类成背景,这个就叫 easy negative, 如果roi里有二分之一个物体,标签仍是负样本,这时候分类器就容易把他看成正样本,这时候就是 hard negative。

确实, 不是一个框中背景和物体越混杂, 越难区分吗? 框中都基本没有物体特征, 不是很容易区分吗?

那么我认为 Fast RCNN 也正是这样做的, 为了解决正负样本不均衡的问题(负例太多了), 我们应该剔除掉一些容易分类负例, 那么与 ground truth 的 IOU 在 [0, 0.1)之间的由于包含物体的特征很少, 应该是很容易分类的, 也就是说是 easy negitive, 为了让算法能够更加有效, 也就是说让算法更加专注于 hard negitive examples, 我们认为 hard negitive examples 包含在[0.1, 0.5) 的可能性很大, 所以训练时, 我们就在[0.1, 0.5)区间做 random sampling, 选择负例.

我们先验的认为 IoU 在[0, 0.1)之内的是 easy example, 但是, [0, 0.1) 中包含 hard negitive examples 的可能性并非没有, 所以我们需要对其做 hard negitive mining, 找到其中的 hard negitive examples 用于训练网络.

按照常理来说 IOU 在[0, 0.1)之内 会被判定为真例的概率很小, 如果这种现象发生了, 可能对于我们训练网络有很大的帮助, 所以 Fast RCNN 会对与 ground truth 的 IoU 在 [0, 0.1)之内的是 example 做 hard negitive examples.

传统 hard example mining 流程

R-CNN 关于 hard negative mining 的部分引用了两篇论文, 下面两句话是摘自这两篇论文中

先要理解什么是 hard negative example?

1. Bootstrapping methods train a model with an initial subset of negative examples, and then collect negative examples that are incorrectly classified by this initial model to form a set of hard negatives. A new model is trained with the hard negative examples, and the process may be repeated a few times.

2. We use the following “bootstrap” strategy that incrementally selects only those “nonface” patterns with high utility value:

  1. Start with a small set of “nonface” examples in the training database.
  2. Train the MLP classifier with the current database of examples.
  3. Run the face detector on a sequence of random images. Collect all the “nonface” patterns that the current system wrongly classifies as “faces” (see Fig. 5b). Add these “nonface” patterns to the training database as new negative examples.
  4. Return to Step2

[17] P. Felzenszwalb, R. Girshick, D. McAllester, and D. Ramanan. Object detection with discriminatively trained part based models. TPAMI, 2010.

[37] K. Sung and T. Poggio. Example-based learning for viewbased human face detection. Technical Report A.I. Memo No. 1521, Massachussets Institute of Technology, 1994.

什么是 hard negative mining?

在 bootstrapping 方法中, 我们先用初始的正负样本(一般是正样本+与正样本同规模的负样本的一个子集)训练分类器, 然后再用训练出的分类器对样本进行分类, 把其中负样本中错误分类的那些样本(hard negative)放入负样本集合, 再继续训练分类器, 如此反复, 直到达到停止条件(比如分类器性能不再提升).

we expect these new examples to help steer the classifier away from its current mistakes.

hard negative 就是每次把那些顽固的棘手的错误, 再送回去继续练, 练到你的成绩不再提升为止. 这一个过程就叫做'hard negative mining'.

R-CNN的实现直接看代码:rcnn/rcnn_train.m at master · rbgirshick/rcnn Line:214开始的函数定义

作者:R2D2
链接:https://www.zhihu.com/question/46292829/answer235112564
来源:知乎, 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载于:https://www.cnblogs.com/nowgood/p/Hardexamplemining.html

### 硬负样本挖掘定义 硬负样本挖掘是指在训练机器学习模型过程中,特别关注那些难以分类或预测错误的负样本实例。这些样本通常位于决策边界附近或是与其他类别有较大重叠区域,因此对于提升模型性能至关重要[^1]。 ### 方法实现 #### 1. 基于损失函数的方法 通过分析每个样例所造成的损失来识别硬负样本。具体来说,在每次迭代后计算所有样本对应的损失值,并从中挑选出具有较高损失值得到误分得更严重的样本作为下一轮训练的重点对象。 ```python def hard_negative_mining(losses, top_k_ratio=0.5): num_samples = int(len(losses) * top_k_ratio) _, indices = torch.topk(losses, k=num_samples) return indices.tolist() ``` 此代码片段展示了如何基于给定的损失列表选取一定比例的最大损失对应索引用于后续处理。 #### 2. Online Hard Example Mining (OHEM) 在线难例挖掘是一种动态调整策略,在每轮更新权重之前先筛选出当前批次中最困难的例子来进行反向传播优化参数。这种方法可以有效减少简单背景干扰项的影响并集中精力改进复杂情况下的表现。 ```python class OHEMLoss(nn.Module): def __init__(self, neg_pos_ratio): super(OHEMLoss, self).__init__() self.neg_pos_ratio = neg_pos_ratio def forward(self, confidences, targets): pos_mask = targets > 0 num_pos = pos_mask.sum().item() if num_pos == 0: # No positive samples found; skip this batch. return None loss_all = F.cross_entropy(confidences.view(-1, 2), targets.view(-1), reduction='none') losses_neg = loss_all[~pos_mask] losses_pos = loss_all[pos_mask] num_neg_to_keep = min(num_pos * self.neg_pos_ratio, len(losses_neg)) if num_neg_to_keep > 0: value, idx = losses_neg.topk(num_neg_to_keep) final_loss = ((losses_pos.sum() + value.sum()) / (num_pos + num_neg_to_keep)).unsqueeze(0) return final_loss ``` 上述Python类实现了带有正负样本比率控制机制的交叉熵损失函数版本,能够自动完成在线难例的选择过程。 ### 应用场景 - **目标检测**:当图像中含有大量非目标物体时,采用硬负样本挖掘技术可以帮助聚焦真正重要的特征; - **人脸识别**:提高对相似面孔区分能力的同时降低误报率; - **异常行为监测**:增强系统对于罕见事件模式的学习效果,从而更好地捕捉潜在威胁信号;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值