RCNN 的 Hard Negative Mining的原理

一、为何难例挖掘? Why Hard Example Mining

        难例挖掘与非极大值抑制 NMS 一样,都是为了解决目标检测老大难问题(样本不平衡+低召回率)及其带来的副作用。

非极大值抑制(NMS)的详解与实现
        首先,目标检测与图像分类不同,图像分类往往只有一个输出,但目标检测的输出个数却是未知的。除了Ground-Truth(标注数据)训练时,模型永远无法百分百确信自己要在一张图上预测多少物体。

     所以目标检测问题的老大难问题之一就是如何提高召回率。召回率(Recall)是模型找到所有某类目标的能力(所有标注的真实边界框有多少被预测出来了)。检测时按照是否检出边界框与边界框是否存在,可以分为下表四种情况:
在这里插入图片描述
        是所有某类物体中被检测出的概率,并由下式给出:
在这里插入图片描述
        为了提高这个值,很直观的想法是“宁肯错杀一千,绝不放过一个”。因此在目标检测中,模型往往会提出远高于实际数量的区域提议(Region Proposal,SSD等one-stage的Anchor也可以看作一种区域提议)。但此时就会遇到一个问题,因为区域提议实在太多,导致在训练时绝大部分都是负样本,这导致了大量无意义负样本的梯度“淹没”了有意义的正样本。根据Focal Loss[1]论文的统计,通常包含少量信息的“easy examples”(通常是负例),与包含有用信息的“hard examples”(正例+难负例)之比为100000:100!这导致这些简单例的损失函数值将是难例损失函数的40倍!在这里插入图片描述
        因此,为了让模型正常训练,我们必须要通过某种方法抑制大量的简单负例,挖掘所有难例的信息,这就是难例挖掘的初衷。

        难负例挖掘(Hard Negative Mining)就是在训练时,尽量多挖掘些难负例(hard negative)加入负样本集,这样会比easy negative组成的负样本集效果更好。

二、R-CNN中的hard negative mining

对于现在的我们,首先遇到难负例挖掘应该是R-CNN的论文,论文关于hard negative mining的部分引用了两篇论文:

  • Object detection with discriminatively trained part based models
  • Example-based learning for viewbased humanface detection
  • 作者:薰风初入弦
    链接:https://www.zhihu.com/question/46292829/answer/794749025
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

        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.
        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 Step 2.
    +而R-CNN中的难负例挖掘就是采用了这种自举法(bootstrap)的方法:
    +先用初始的正负样本训练分类器(此时为了平衡数据,使用的负样本也只是所有负样本的子集)
  • 用(1)训练好的分类器对样本进行分类,把其中错误分类的那些样本(hard negative)放入负样本子集,
  • 再继续训练分类器,
  • 如此反复,直到达到停止条件(比如分类器性能不再提升).
    也就是说,R-CNN的Hard Negative Mining相当于给模型定制一个错题集,在每轮训练中不断“记错题”,并把错题集加入到下一轮训练中,直到网络效果不能上升为止。
    R-CNN中Hard Negative Mining的实现代码:
    rcnn/rcnn_train.m at master · rbgirshick/rcnnLine:214开始的函数定义
    在源文件rcnn_train.m中函数 sample_negative_feature用于采样负例特征,对函数定义的关键代码稍作解释。
d.feat = rcnn_pool5_to_fcX(d.feat, opts.layer, rcnn_model); %将pool5层特征前向传播到fc7层特征
d.feat = rcnn_scale_features(d.feat, opts.feat_norm_mean); % 缩放特征norm值,具体参见源码注释
neg_ovr_thresh = 0.3;
if first_time     % 首次直接取 最大IOU < 0.3 的region作为负例,用于后面训练SVM
  for cls_id = class_ids
    I = find(d.overlap(:, cls_id) < neg_ovr_thresh);
    X_neg{cls_id} = d.feat(I,:);
    keys{cls_id} = [ind*ones(length(I),1) I];
  end
else   % 非首次负例采样
 % 先用当前更新过的SVM 预测region,即,应用SVM到 fc7的特征上,y'=w*x+b
  zs = bsxfun(@plus, d.feat*rcnn_model.detectors.W, rcnn_model.detectors.B);
  for cls_id = class_ids % 每个分类独立使用SVM
    z = zs(:, cls_id);   % 对当前分类,获取 SVM 计算值 y'
 % 下一行代码是关键
    I = find((z > caches{cls_id}.hard_thresh) & ...
             (d.overlap(:, cls_id) < neg_ovr_thresh));
% Avoid adding duplicate features
    keys_ = [ind*ones(length(I),1) I];
    if ~isempty(caches{cls_id}.keys_neg) && ~isempty(keys_)
      [~, ~, dups] = intersect(caches{cls_id}.keys_neg, keys_, 'rows');
      keep = setdiff(1:size(keys_,1), dups);
      I = I(keep);
    end
% Unique hard negatives
    X_neg{cls_id} = d.feat(I,:);
    keys{cls_id} = [ind*ones(length(I),1) I];
  end
end

上述代码片段中,非首次负例采样时,要筛选出 难负例example,需要满足两个条件:

  • 负例,即最大IOU 小于 阈值 d.overlap(:, cls_id) < neg_ovr_thresh
  • 分类错误,既然是负例,那么SVM计算值wx+b 应该小于 1
    以下图简单的回顾一下SVM:
    在这里插入图片描述位于H1和H2超平面上的实例就称为支持向量机对于y=1的正例点,有H1: wx + b =1
    对于y=-1的负例点,H2: wx + b = -1
    分类正确时应满足,
    1)wx+b>=1, if y = 1
    2)wx+b <=-1, if y = -1
    但是,SVM为了处理非严格线性可分的数据集,引入了松弛变量,于是如下图,在这里插入图片描述
    于是 只要 wx+b>-1,都可以认为是正例,只不过 wx+b越小,置信度越低。
    在inference阶段,同样是这个思路,比如rcnn_detect.m文件中
thresh = -1
scores = bsxfun(@plus, feat*rcnn_model.detectors.W, rcnn_model.detectors.B);
for i = 1:num_classes
  I = find(scores(:, i) > thresh);
  scored_boxes = cat(2, boxes(I, :), scores(I, i));
  keep = nms(scored_boxes, 0.3); 
  dets{i} = scored_boxes(keep, :);
end

参考博客

Hard negative mining
rcnn中的Hard negative mining方法是如何实现的?

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Hard negative mining(困难负样本挖掘)是一种用于目标检测和分类任务的训练策略。在这种方法中,模型会专门关注那些被错误分类的负样本,以便更好地学习和纠正分类器的错误。 在传统的目标检测或分类任务中,通常使用大量的负样本和正样本进行模型训练。然而,由于负样本远远超过正样本,其中很多负样本可能是相对容易分类的,而对于模型来说,这些负样本并没有提供太多的学习信息。因此,Hard negative mining方法旨在筛选出那些被错误分类的难以区分的负样本,并将其加入训练集中,以便模型能够更好地学习和区分这些困难的负样本。 具体而言,Hard negative mining方法通常包括以下步骤: 1. 使用当前模型对训练集中的所有样本进行预测。 2. 根据预测结果和真实标签,确定哪些负样本被错误分类。 3. 选择被错误分类的负样本作为困难负样本,并将其加入训练集中。 4. 使用扩充后的训练集重新训练模型。 通过重复这个过程,模型能够更加关注那些难以区分的负样本,从而提高模型对负样本的分类能力。 Hard negative mining方法的优势在于提高了模型对难以区分负样本的分类能力,从而改善了模型的性能。然而,需要注意的是,这种方法也可能引入一些噪声,因为有些被错误分类的负样本实际上可能是噪声或特定场景下的异常情况。因此,在应用Hard negative mining方法时,需要平衡好正负样本的比例,并谨慎选择用于训练的困难负样本。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

☞源仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值