PyTorch中提供了很多种损失函数,常用于分类的是 torch.nn.BCELoss()、torch.nn.BCEWithLogitsLoss() 和 torch.nn.CrossEntropyLoss()
其中,torch.nn.BCELoss()、torch.nn.BCEWithLogitsLoss() 用于二分类问题, torch.nn.CrossEntropyLoss() 既可用于二分类又可用于多分类
以下对这三项进行辨析(PyTorch 1.8.0)
1、torch.torch.nn.BCELoss()
此损失函数衡量输出与目标之间的二分类交叉熵
torch.torch.nn.BCELoss(weight=None, reduction='mean')
weight:默认 None,用于计算损失的手动尺度化的权重,张量
reduction:默认 'mean',指定应用于输出的缩减方式,另可选 'none','sum';'none':不应用缩减;'mean':输出的和除以输出内元素数;'sum':输出加和
输入:input -- 形状为,为样本数量,为任意其他维度
输入:target -- 形状,形状同input
输出:output -- 标量(reduction若为none,则形状同input)
未缩减的 loss 可以表示为:
其中是 batch 的大小;
如果参数 reduction 不是 'none',则有:
目标 应为0到1之间的数字;
BCELoss 将log函数的输出限定为始终大于等于-100;
2、torch.nn.BCEWithLogitsLoss()
此损失函数将 Sigmoid 层和 BCELoss 整合在一起
比简单地将 Sigmoid 层加上 BCELoss 损失更稳定,因为使用了 log-sun-exp 技巧获得数值稳定性
torch.nn.BCEWithLogitsLoss(weight=None, reduction='mean', pos_weight=None)
weight:默认 None,用于计算损失的手动尺度化的权重,张量
reduction:默认 'mean',指定应用于输出的缩减方式,另可选 'none','sum';'none':不应用缩减;'mean':输出的和除以输出内元素数;'sum':输出加和
pos_weight:默认 None,正例的权重,需为长度为类别数的向量;
输入:input -- 形状为,为样本数量,为任意其他维度
输入:target -- 形状,形状同input
输出:output -- 标量(reduction若为none,则形状同input)
未缩减的 loss 可以表示为:
其中是 batch 的大小;
如果参数 reduction 不是 'none',则有:
目标 应为0到1之间的数字;
可以通过为正例赋权值来平衡 recall 和 precision;
在多标签分类中,loss 可以表示为:
其中 为类的数量,大于1时为多标签二分类,等于1时为单标签二分类问题;
为对 类分为正例的权重,大于1时会增大 recall,小于1时增加 precision;
如果数据集包含20个正例样本,100个负例样本,则 pos_weight 中此类的权重为100/20=5,此时计算loss时犹如数据包含5*20=100个正例样本;
3、torch.nn.CrossEntropyLoss()
此损失函数将 LogSoftmax 和 NLLLoss 的特点进行了整合,用于类的分类问题
torch.nn.CrossEntropyLoss(weight=None, ignore_index=-100, reduction='mean')
weight:默认 None,用于计算损失的手动尺度化的权重,大小为的一维张量
ignore_index:默认-100,指定对输入梯度无贡献的应被忽略的目标值的阈值
reduction:默认'mean',指定应用于输出的缩减方式,另可选 'none','sum';'none':不应用缩减;'mean':输出的和除以输出内元素数;'sum':输出加和
输入:input -- 形状为,为样本数量,为类别数,输入应为原始的未经标准化的每一类的得分;
输入:target -- 形状,将类的索引作为目标值;
输出:output -- 标量(reduction若为none,则形状同target)
loss可以表示为:
当 weight 参数指定时:
loss 对每个minibatch在所有样本上平均,weight指定时有加权平均:
其中是 batch 的大小;