MMDetection为用户提供不同的丢失功能。但是默认配置可能不适用于不同的数据集或模型,因此用户可能希望修改特定的损失以适应新的情况。
给定输入预测和目标,以及权值,损失函数将输入张量映射到最终损失标量。映射可以分为四个步骤:
对于某些损失函数,需要采取抽样策略来避免正样本和负样本之间的不平衡。
例如,当在RPN头部使用CrossEntropyLoss时,我们需要在train_cfg中设置RandomSampler
train_cfg=dict(
rpn=dict(
sampler=dict(
type='RandomSampler',
num=256,
pos_fraction=0.5,
neg_pos_ub=-1,
add_gt_as_proposals=False))
对于具有正负样品平衡机制的其他损失,如FocalLoss、GHMC和QualityFocalLoss,则不再需要采样器。
调整损失与步骤2、步骤4、步骤5更相关,大多数修改都可以在配置中指定。这里我们以Focal Loss (FL)为例。下面的代码狙击手分别是FL的构造方法和配置,它们实际上是一一对应的。
@LOSSES.register_module()
class FocalLoss(nn.Module):
def __init__(self,
use_sigmoid=True,
gamma=2.0,
alpha=0.25,
reduction='mean',
loss_weight=1.0):
loss_cls=dict(
type='FocalLoss',
use_sigmoid=True,
gamma=2.0,
alpha=0.25,
loss_weight=1.0)
gamma和beta是焦损的两个超参数。假设我们想要将gamma值改为1.5,alpha值改为0.5,那么我们可以在配置中如下所示指定它们:
loss_cls=dict(
type='FocalLoss',
use_sigmoid=True,
gamma=1.5,
alpha=0.5,
loss_weight=1.0)
对于FL,约简的默认方式是mean。例如,如果我们想要将约简从mean更改为sum,我们可以在配置中指定如下:
loss_cls=dict(
type='FocalLoss',
use_sigmoid=True,
gamma=2.0,
alpha=0.25,
loss_weight=1.0,
reduction='sum')
这里的损失权值是一个标量,它控制多任务学习中不同损失的权值,例如分类损失和回归损失。例如,如果我们想将分类损失的损失权重改为0.5,我们可以在配置中如下所示:
loss_cls=dict(
type='FocalLoss',
use_sigmoid=True,
gamma=2.0,
alpha=0.25,
loss_weight=0.5)
加权损失意味着我们明智地重新加权损失元素。更具体地说,我们将损失张量与一个具有相同形状的权张量相乘。因此,损失的不同分项可以按不同的比例计算,这就是所谓的“要素”。损失权值在不同的模型中是不同的,并且与上下文高度相关,但总体上有两种损失权值,用于分类损失的label_weights和用于框回归损失的bbox_weights。您可以在相应头部的get_target方法中找到它们。这里我们以atshead为例,它继承了AnchorHead但是覆盖了它的get_targets方法,从而产生了不同的label_weights和bbox_weights。
lass ATSSHead(AnchorHead):
...
def get_targets(self,
anchor_list,
valid_flag_list,
gt_bboxes_list,
img_metas,
gt_bboxes_ignore_list=None,
gt_labels_list=None,
label_channels=1,
unmap_outputs=True):