大家好,又见面了,我是你们的朋友全栈君。
OHEM(online hard example miniing)
详细解读一下OHEM的实现代码:
def ohem_loss(
batch_size, cls_pred, cls_target, loc_pred, loc_target, smooth_l1_sigma=1.0
):
"""
Arguments:
batch_size (int): number of sampled rois for bbox head training
loc_pred (FloatTensor): [R, 4], location of positive rois
loc_target (FloatTensor): [R, 4], location of positive rois
pos_mask (FloatTensor): [R], binary mask for sampled positive rois
cls_pred (FloatTensor): [R, C]
cls_target (LongTensor): [R]
Returns:
cls_loss, loc_loss (FloatTensor)
"""
ohem_cls_loss = F.cross_entropy(cls_pred, cls_target, reduction='none', ignore_index=-1)
ohem_loc_loss = smooth_l1_loss(loc_pred, loc_target, sigma=smooth_l1_sigma, reduce=False)
#这里先暂存下正常的分类loss和回归loss
loss = ohem_cls_loss + ohem_loc_loss
#然后对分类和回归loss求和
sorted_ohem_loss, idx = torch.sort(loss, descending=True)
#再对loss进行降序排列
keep_num = min(sorted_ohem_loss.size()[0], batch_size)
#得到需要保留的loss数量
if keep_num < sorted_ohem_loss.size()[0]:
#这句的作用是如果保留数目小于现有loss总数,则进行筛选保留,否则全部保留
keep_idx_cuda = idx[:keep_num]
#保留到需要keep的数目
ohem_cls_loss = ohem_cls_loss[keep_idx_cuda]
ohem_loc_loss = ohem_loc_loss[keep_idx_cuda]
#分类和回归保留相同的数目
cls_loss = ohem_cls_loss.sum() / keep_num
loc_loss = ohem_loc_loss.sum() / keep_num
#然后分别对分类和回归loss求均值
return cls_loss, loc_loss
为什么要叫在线难例最小化呢?
因为在深度学习提出这个方法的人,想和传统方法区分开。难例挖掘,机器学习学习中尤其是在svm中早就已经使用,又称为bootstrapping。
传统的难例挖掘流程:首先是通过训练集训练网络,训练完成,然后固定网络,寻找新的样本,加入到训练集中。很显然这将耗费很长的时间。
因此作者提出的是在线难例挖掘。
具体怎么实现的呢?
通常是搬出这张图,说实话这张图有点啰嗦!
按我的理解,OHEM的操作就是舍弃了faster RCNN中的正负样本(ROI)比例为1:3,它通过每个ROI的loss值,对所有roi的loss排序,取B/N数量的roi组成mini batch。注意:对于指向同一个目标的rois,通过NMS,取loss最大的roi,其他都删除。
也就是通过loss提高难样本的比例,让网络花更多精力去学习难样本。
我觉得它和focal loss思路本质是一样的,focal loss把loss作用在类别上,二目标检测OHEM把loss 作用在ROI上。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/139244.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...