目标检测,一般分为2个部分,定位和分类,example mining是选择出特定样本来计算损失函数;从实际问题出发hard example应该就是指定位较困难或分类较困难或者两者都困难的候选框。SSD的caffe中支持negative mining和hard example mining,当share_location参数为true时,只支持negative mining。
对于给定候选框,其位置是确定的,那么定位的困难度用其到所有gt_bboxes之间的距离来度量,相当于求一个点到一个集合之间的距离;而分类困难度很好理解,即可定义为交叉熵损失($-log(p_i)$)。在SSD中,所有的prior_bboxes或default bboxes是可事先计算好的,其数目是确定的,对于每个default bbox仅仅根据gt_bboxes就可以确定其定位损失,与CNN无关;但是对于分类损失需要计算CNN特征。
Hard negative example或Hard positive example的定义需要首先确定某个候选框是negative example还是positive example。比如SSD中将与任意gt_bbox的IOU超过给定阈值overlap_threshold(multibox_loss_param中的一个字段,SSD默认为0.5)的当作正样本,即前景类别为正样本,背景类别为负样本。比如,极端的例子,当图像中没有gt_bbox时,那么所有的default bboxes都是negative example。
SSD中negative mining只计算分类损失而不计算定位损失,而hard example mining对分类损失和定位损失都进行计算。
SSD的negative mining的过程为:1)将每个default box与gt_bbox匹配;2)当第i个bbox被匹配到第j个gt_bbox,那么计算其属于背景类别的softmax loss或cross entropy loss值; 3)按照loss排序,选择loss较大且与任意gt_bbox之间的iou小于neg_overlap的前3*num_positive个负样本。
在选择样本时,由于每个feature map上的点对应6个default boxes,所有负样本成堆出现,那么为了减少负样本数,可以采用非极大值抑制,此时非极大值抑制的阈值为负样本的分类损失和定位损失之和的一个阈值。
// Do non-maximum suppression based on the loss.
vector<int> nms_indices;
ApplyNMS(sel_bboxes, sel_loss, nms_threshold, top_k, &nms_indices);
if (nms_indices.size() < num_sel) {
LOG(INFO) << "not enough sample after nms: " << nms_indices.size();
}
// Pick top example indices after nms.
num_sel = std::min(static_cast<int>(nms_indices.size()), num_sel);
for (int n = 0; n < num_sel; ++n) {
sel_indices.insert(loss_indices[nms_indices[n]].second);
}
采用Hard example minng的layer层为:
layer {
name: "loss"
type: "MultiBoxLoss"
bottom: "mbox_loc"
bottom: "mbox_conf"
bottom: "mbox_priorbox"
bottom: "label"
top: "loss"
include {
phase: TRAIN
}
propagate_down: true
propagate_down: true
propagate_down: false
propagate_down: false
loss_param {
normalization: VALID
}
multibox_loss_param {
loc_loss_type: SMOOTH_L1
conf_loss_type: SOFTMAX
loc_weight: 1.0
num_classes: 2
share_location: true #所有前景类别是否共享default bbox
match_type: PER_PREDICTION
overlap_threshold: 0.5 #default bbox为正样本的条件是iou>overlap_threshold
use_prior_for_matching: true #直接使用default bbox匹配pred_bbox
background_label_id: 0
use_difficult_gt: true
#neg_pos_ratio: 3.0 #负正样本数比例,只有MAX_NEGATIVE mining时才有用
neg_overlap: 0.5 #default bbox为负样本的条件是:iou<neg_overlap
code_type: CENTER_SIZE
ignore_cross_boundary_bbox: false
#mining_type: MAX_NEGATIVE
mining_type: HARD_EXAMPLE #后面的3个参数只用在此种mining中
nms_param {
nms_threshold: 1e-5
top_k: 100
}
sample_size: 2
use_prior_for_nms: true
}
}
SSD中Hard example mining和negative mining的区别在于:
1) Hard example多一个location loss;
2)negative mining按正负样本比例确定负样本数;Hard example选出的样本数要少于等于multibox_loss_param中的参数sample_size。
3)Hard example会对匹配阶段的结果进行修改从而减少正样本数,如果即使box_i与gt_bbox_j匹配了,但在按loc_loss+conf_loss排序时比较大,匹配算无效的,即该匹配的box_i不会被当作正样本。