YOLOV5中损失函数即代码讲解
YOLOV5中loss.py文件代码讲解:
yolov5中一共存在三种损失函数:
分类损失cls_loss:计算锚框与对应的标定分类是否正确
定位损失box_loss:预测框与标定框之间的误差(CIoU)
置信度损失obj_loss:计算网络的置信度
通过交叉熵损失函数与对数损失的结合来计算定位损失以及分类损失。
class BCEBlurWithLogitsLoss(nn.Module):#二元交叉熵损失函数,blur 意为模糊 据下行原版注释是减少了错失标签带来的影响
# BCEwithLogitLoss() with reduced missing label effects.
def __init__(self, alpha=0.05):
super(BCEBlurWithLogitsLoss, self).__init__()
# 这里BCEWithLogitsLoss 是输入的每一个元素带入sigmoid函数之后 再同标签计算BCE loss
self.loss_fcn = nn.BCEWithLogitsLoss(reduction='none') # must be nn.BCEWithLogitsLoss()
self.alpha = alpha#这个应该算是一个模糊系数吧 默认为0.05
def forward(self, pred, true):
# 得到了预测值和标签值的BCE loss 注:预测值是经过sigmoid函数处理再计算BCE的
loss = self.loss_fcn(pred, true)
pred = torch.sigmoid(pred) # prob from logits # 将预测值进行sigmoid处理 数学意义为每一位对应类别出现的概率
# 假定missing的标签用一行0进行补齐,则相减之后missing的样本概率不受影响,正常样本样本概率为绝对值较小的负数
dx = pred - true # reduce only missing label effects
# dx = (pred - true).abs() # reduce missing label and false label effects
"""
torch.exp()函数就是求e的多少次方 输入tensor每一个元素经过计算之后返回对应的tensor
根据下式 对于正常的较大概率的样本 dx对应值为绝对值较小一个负数 假设为-0.12,则-1为-1.12除0.05 为-22.4,
-22.4 指数化之后为一个很小很小的正数,1-该正数之后得到的值较大 再在loss中乘上之后影响微乎其微
而对于missing的样本 dx对应为一个稍大的正数 如0.3 减去1之后为-0.7 除以0.05 为 -14
-14相比-22.4值为指数级增大,因此对应的alpha_factor相比正常样本显著减小 在loss中较小考虑
"""
# Q:有一个问题,为什么yolov5要对missing的样本有这样的容忍度,而不是选择直接屏蔽掉对应样本呢?
alpha_factor = 1 - torch.exp((dx - 1) / (self.alpha + 1e-4))
loss *= alpha_factor
return loss.mean() # 这个mean的意义应该为对一批batch中的每一个样本得到的BCE loss求均值作为返回值
二分类交叉熵损失函数
之前的分类损失是各个训练样本交叉熵的直接求和,也就是各个样本的权重是一样的,计算公式如下:
因为是二分类,p表示预测样本属于1时的概率,y表示标签,y的取值范围为{+1,-1}
对于正样本的预测,预测输出越接近真实样本标签y=1, 损失函数L越小;预测输出越接近0,L越大。
Focal Loss损失函数讲解
focal loss,这个损失函数是在标准交叉熵损失基础上修改得到的