损失函数理解汇总,结合PyTorch1.7和TensorFlow2
极市导读
本文总结讨论了在深度学习中常用的十余种损失函数(含变种),结合PyTorch和TensorFlow2对其概念、公式及用途进行阐述,对大家各种损失函数有个大致的了解以及使用。 >>加入极市CV技术交流群,走在计算机视觉的最前沿
TensorFlow2.3 PyTorch1.7.0
01 交叉熵损失(CrossEntropyLoss)
对于单事件的信息量而言,当事件发生的概率越大时,信息量越小,需要明确的是,信息量是对于单个事件来说的,实际事件存在很多种可能,所以这个时候熵就派上用场了,熵是表示随机变量不确定的度量,是对所有可能发生的事件产生的信息量的期望。交叉熵用来描述两个分布之间的差距,交叉熵越小,假设分布离真实分布越近,模型越好。
在分类问题模型中(不一定是二分类),如逻辑回归、神经网络等,在这些模型的最后通常会经过一个sigmoid函数(softmax函数),输出一个概率值(一组概率值),这个概率值反映了预测为正类的可能性(一组概率值反应了所有分类的可能性)。而对于预测的概率分布和真实的概率分布之间,使用交叉熵来计算他们之间的差距,换句不严谨的话来说,交叉熵损失函数的输入,是softmax或者sigmoid函数的输出。交叉熵损失可以从理论公式推导出几个结论(优点),具体公式推导不在这里详细讲解,如下:
预测的值跟目标值越远时,参数调整就越快,收敛就越快;
不会陷入局部最优解
交叉熵损失函数的标准形式(也就是二分类交叉熵损失)如下:
BinaryCrossentropy[1]:二分类,经常搭配Sigmoid使用
tf.keras.losses.BinaryCrossentropy(from_logits=False, label_smoothing=0, reduction=losses_utils.ReductionV2.AUTO, name='binary_crossentropy')
参数:
from_logits:默认False。为True,表示接收到了原始的logits,为False表示输出层经过了概率处理(softmax)
label_smoothing:[0,1]之间浮点值,加入噪声,减少了真实样本标签的类别在计算损失函数时的权重,最终起到抑制过拟合的效果。
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
binary_crossentropy[2]
tf.keras.losses.binary_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0)
参数:
from_logits:默认False。为True,表示接收到了原始的logits,为False表示输出层经过了概率处理(softmax)
label_smoothing:[0,1]之间浮点值,加入噪声,减少了真实样本标签的类别在计算损失函数时的权重,最终起到抑制过拟合的效果。
CategoricalCrossentropy[3]:多分类,经常搭配Softmax使用
tf.keras.losses.CategoricalCrossentropy(from_logits=False, label_smoothing=0, reduction=losses_utils.ReductionV2.AUTO, name='categorical_crossentropy')
参数:
from_logits:默认False。为True,表示接收到了原始的logits,为False表示输出层经过了概率处理(softmax)
label_smoothing:[0,1]之间浮点值,加入噪声,减少了真实样本标签的类别在计算损失函数时的权重,最终起到抑制过拟合的效果。
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
categorical_crossentropy[4]
tf.keras.losses.categorical_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0)
参数:
from_logits:默认False。为True,表示接收到了原始的logits,为False表示输出层经过了概率处理(softmax)
label_smoothing:[0,1]之间浮点值,加入噪声,减少了真实样本标签的类别在计算损失函数时的权重,最终起到抑制过拟合的效果。
SparseCategoricalCrossentropy[5]:多分类,经常搭配Softmax使用,和CategoricalCrossentropy不同之处在于,CategoricalCrossentropy是one-hot编码,而SparseCategoricalCrossentropy使用一个位置整数表示类别
tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False, reduction=losses_utils.ReductionV2.AUTO, name='sparse_categorical_crossentropy')
参数:
from_logits:默认False。为True,表示接收到了原始的logits,为False表示输出层经过了概率处理(softmax)
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
sparse_categorical_crossentropy[6]
tf.keras.losses.sparse_categorical_crossentropy(y_true, y_pred, from_logits=False, axis=-1)
参数:
from_logits:默认False。为True,表示接收到了原始的logits,为False表示输出层经过了概率处理(softmax)
axis:默认是-1,计算交叉熵的维度
BCELoss[7]
torch.nn.BCELoss(weight: Optional[torch.Tensor] = None, size_average=None, reduce=None, reduction: str = 'mean')
参数:
weight:每个分类的缩放权重,传入的大小必须和类别数量一至
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction:string类型,'none' | 'mean' | 'sum'三种参数值
BCEWithLogitsLoss[8]:其实和TensorFlow是的`from_logits`参数很像,在BCELoss的基础上合并了Sigmoid
torch.nn.BCEWithLogitsLoss(weight: Optional[torch.Tensor] = None, size_average=None, reduce=None, reduction: str = 'mean', pos_weight: Optional[torch.Tensor] = None)
参数:
weight:每个分类的缩放权重,传入的大小必须和类别数量一至
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction:string类型,'none' | 'mean' | 'sum'三种参数值
pos_weight:正样本的权重, 当p>1,提高召回率,当p<1,提高精确度。可达到权衡召回率(Recall)和精确度(Precision)的作用。
CrossEntropyLoss[9]
torch.nn.CrossEntropyLoss(weight: Optional[torch.Tensor]
= None, size_average=None, ignore_index: int = -100,
reduce=None, reduction: str = 'mean')
参数:
weight:每个分类的缩放权重,传入的大小必须和类别数量一至
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
ignore_index:忽略某一类别,不计算其loss,其loss会为0,并且,在采用size_average时,不会计算那一类的loss,除的时候的分母也不会统计那一类的样本
reduce:bool类型,返回值是否为标量,默认为True
reduction:string类型,'none' | 'mean' | 'sum'三种参数值
02 KL散度
我们在计算预测和真实标签之间损失时,需要拉近他们分布之间的差距,即模型得到的预测分布应该与数据的实际分布情况尽可能相近。KL散度(相对熵)是用来衡量两个概率分布之间的差异。模型需要得到最大似然估计,乘以负Log以后就相当于求最小值,此时等价于求最小化KL散度(相对熵)。所以得到KL散度就得到了最大似然。又因为KL散度中包含两个部分,第一部分是交叉熵,第二部分是信息熵,即KL=交叉熵−信息熵。信息熵是消除不确定性所需信息量的度量,简单来说就是真实的概率分布,而这部分是固定的,所以优化KL散度就是近似于优化交叉熵。下面是KL散度的公式:
联系上面的交叉熵,我们可以将公式简化为(KL散度 = 交叉熵 - 熵):
监督学习中,因为训练集中每个样本的标签是已知的,此时标签和预测的标签之间的KL散度等价于交叉熵。
KLD | kullback_leibler_divergence[10]
tf.keras.losses.KLD(y_true, y_pred)
KLDivergence[11]
tf.keras.losses.KLDivergence(reduction=losses_utils.ReductionV2.AUTO, name='kl_divergence')
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
KLDivLoss[12]
torch.nn.KLDivLoss(size_average=None, reduce=None, reduction: str = 'mean', log_target: bool = False)
参数:
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean
log_target:默认False,指定是否在日志空间中传递目标
03 平均绝对误差(L1范数损失)
梯度恒定,不论预测值是否接近真实值,这很容易导致发散,或者错过极值点。 导数不连续,导致求解困难。这也是L1损失函数不广泛使用的主要原因。
收敛速度比L2损失函数要快,这是通过对比函数图像得出来的,L1能提供更大且稳定的梯度。 对异常的离群点有更好的鲁棒性,下面会以例子证实。
MAE | mean_absolute_error[13]
tf.keras.losses.MAE(y_true, y_pred)
MeanAbsoluteError[14]
tf.keras.losses.MeanAbsoluteError(reduction=losses_utils.ReductionV2.AUTO, name='mean_absolute_error')
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
MeanAbsolutePercentageError[15]:平均绝对百分比误差
tf.keras.losses.MeanAbsolutePercentageError(reduction=losses_utils.ReductionV2.AUTO, name='mean_absolute_percentage_error')
公式:loss = 100 * abs(y_true - y_pred) / y_true
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
MAPE | mean_absolute_percentage_error[16]:平均绝对百分比误差
tf.keras.losses.MAPE(y_true, y_pred)
公式:loss = 100 * mean(abs((y_true - y_pred) / y_true), axis=-1)
Huber[17]
tf.keras.losses.Huber(delta=1.0, reduction=losses_utils.ReductionV2.AUTO, name='huber_loss')
公式:error = y_true - y_pred
参数:
delta:float类型,Huber损失函数从二次变为线性的点。
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
L1Loss[18]
torch.nn.L1Loss(size_average=None, reduce=None, reduction: str = 'mean')
参数:
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean
l1_loss[19]
torch.nn.functional.l1_loss(input, target, size_average=None, reduce=None, reduction='mean')
SmoothL1Loss[20]:平滑版L1损失,也被称为 Huber 损失函数。
torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction: str = 'mean', beta: float = 1.0)
参数:
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean
beta:默认为1,指定在L1和L2损耗之间切换的阈值
smooth_l1_loss[21]
torch.nn.functional.smooth_l1_loss(input, target, size_average=None, reduce=None, reduction='mean', beta=1.0)
04 均方误差损失(L2范数损失)
收敛速度比L1慢,因为梯度会随着预测值接近真实值而不断减小。 对异常数据比L1敏感,这是平方项引起的,异常数据会引起很大的损失。
它使训练更容易,因为它的梯度随着预测值接近真实值而不断减小,那么它不会轻易错过极值点,但也容易陷入局部最优。 它的导数具有封闭解,优化和编程非常容易,所以很多回归任务都是用MSE作为损失函数。
MeanSquaredError[22]
tf.keras.losses.MeanSquaredError(reduction=losses_utils.ReductionV2.AUTO, name='mean_squared_error')
公式:loss = square(y_true - y_pred)
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
MSE | mean_squared_error[23]
tf.keras.losses.MSE(y_true, y_pred)公式:loss = mean(square(y_true - y_pred), axis=-1)
MeanSquaredLogarithmicError[24]
tf.keras.losses.MeanSquaredLogarithmicError(reduction=losses_utils.ReductionV2.AUTO, name='mean_squared_logarithmic_error')
公式:loss = square(log(y_true + 1.) - log(y_pred + 1.))
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
MSLE | mean_squared_logarithmic_error[25]
tf.keras.losses.MSLE(y_true, y_pred)
公式:loss = mean(square(log(y_true + 1) - log(y_pred + 1)), axis=-1)
MSELoss[26]
torch.nn.MSELoss(size_average=None, reduce=None, reduction: str = 'mean')
参数:
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean
mse_loss[27]
torch.nn.functional.mse_loss(input, target, size_average=None, reduce=None, reduction='mean')
05 Hinge loss
CategoricalHinge[28]
tf.keras.losses.CategoricalHinge(reduction=losses_utils.ReductionV2.AUTO, name='categorical_hinge')
公式:loss = maximum(neg - pos + 1, 0) where neg=maximum((1-y_true)*y_pred) and pos=sum(y_true*y_pred)
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
categorical_hinge[29]
tf.keras.losses.categorical_hinge(y_true, y_pred)
公式:loss = maximum(neg - pos + 1, 0) where neg=maximum((1-y_true)*y_pred) and pos=sum(y_true*y_pred)
Hinge[30]
tf.keras.losses.Hinge(
reduction=losses_utils.ReductionV2.AUTO, name='hinge'
)
公式:loss = maximum(1 - y_true * y_pred, 0),y_true值应为-1或1。如果提供了二进制(0或1)标签,会将其转换为-1或1
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
hinge[31]
tf.keras.losses.hinge(y_true, y_pred)
公式:loss = mean(maximum(1 - y_true * y_pred, 0), axis=-1)
SquaredHinge[32]
tf.keras.losses.SquaredHinge(
reduction=losses_utils.ReductionV2.AUTO, name='squared_hinge'
)
公式:loss = square(maximum(1 - y_true * y_pred, 0)),y_true值应为-1或1。如果提供了二进制(0或1)标签,会将其转换为-1或1。
参数:
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
squared_hinge[33]
tf.keras.losses.squared_hinge(y_true, y_pred)
公式:loss = mean(square(maximum(1 - y_true * y_pred, 0)), axis=-1)
HingeEmbeddingLoss[34]:当 时, ,当 时,
torch.nn.HingeEmbeddingLoss(margin: float = 1.0, size_average=None, reduce=None, reduction: str = 'mean')
参数:
margin:float类型,默认为1.
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean
06 余弦相似度
CosineSimilarity[35]:请注意,所得值是介于-1和0之间的负数,其中0表示正交性,而接近-1的值表示更大的相似性。如果y_true或y_pred是零向量,则余弦相似度将为0,而与预测值和目标值之间的接近程度无关。
tf.keras.losses.CosineSimilarity(axis=-1, reduction=losses_utils.ReductionV2.AUTO, name='cosine_similarity')
公式:loss = -sum(l2_norm(y_true) * l2_norm(y_pred))
参数:
axis:默认-1,沿其计算余弦相似度的维
reduction:传入tf.keras.losses.Reduction类型值,默认AUTO,定义对损失的计算方式。
cosine_similarity[36]
tf.keras.losses.cosine_similarity(y_true, y_pred, axis=-1)
公式:loss = -sum(l2_norm(y_true) * l2_norm(y_pred))
参数:
axis:默认-1,沿其计算余弦相似度的维
CosineEmbeddingLoss[37]:当 时, ,当 时,
torch.nn.CosineEmbeddingLoss(margin: float = 0.0, size_average=None, reduce=None, reduction: str = 'mean')
参数:
margin:float类型,应为-1到1之间的数字,建议为0到0.5,默认值为0
size_average:bool类型,为True时,返回的loss为平均值,为False时,返回的各样本的loss之和
reduce:bool类型,返回值是否为标量,默认为True
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean
7 总结
外链地址:
[1] https://www.tensorflow.org/api_docs/python/tf/keras/losses/BinaryCrossentropy
[2] https://www.tensorflow.org/api_docs/python/tf/keras/losses/binary_crossentropy
[3] https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy
[4] https://www.tensorflow.org/api_docs/python/tf/keras/losses/categorical_crossentropy
[5] https://www.tensorflow.org/api_docs/python/tf/keras/losses/SparseCategoricalCrossentropy
[6] https://www.tensorflow.org/api_docs/python/tf/keras/losses/sparse_categorical_crossentropy
[7] https://pytorch.org/docs/stable/generated/torch.nn.BCELoss.html
[8] https://pytorch.org/docs/stable/generated/torch.nn.BCEWithLogitsLoss.html
[9] https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html
[10] https://www.tensorflow.org/api_docs/python/tf/keras/losses/KLD
[11] https://www.tensorflow.org/api_docs/python/tf/keras/losses/KLDivergence
[12] https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html
[13] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MAE
[14] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanAbsoluteError
[15] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanAbsolutePercentageError
[16] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MAPE
[17] https://www.tensorflow.org/api_docs/python/tf/keras/losses/Huber
[18] https://pytorch.org/docs/stable/generated/torch.nn.L1Loss.html
[19] https://pytorch.org/docs/stable/nn.functional.html?highlight=loss#torch.nn.functional.l1_loss
[20] https://pytorch.org/docs/stable/generated/torch.nn.SmoothL1Loss.html
[21] https://pytorch.org/docs/stable/nn.functional.html?highlight=loss#torch.nn.functional.smooth_l1_loss
[22] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanSquaredError
[23] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MSE
[24] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanSquaredLogarithmicError
[25] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MSLE
[26] https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html
[27] https://pytorch.org/docs/stable/nn.functional.html?highlight=loss#torch.nn.functional.mse_loss
[28] https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalHinge
[29] https://www.tensorflow.org/api_docs/python/tf/keras/losses/categorical_hinge
[30] https://www.tensorflow.org/api_docs/python/tf/keras/losses/Hinge
[31] https://www.tensorflow.org/api_docs/python/tf/keras/losses/hinge
[32] https://www.tensorflow.org/api_docs/python/tf/keras/losses/SquaredHinge
[33] https://www.tensorflow.org/api_docs/python/tf/keras/losses/squared_hinge
[34] https://pytorch.org/docs/stable/generated/torch.nn.HingeEmbeddingLoss.html
[35] https://www.tensorflow.org/api_docs/python/tf/keras/losses/CosineSimilarity
[36] https://www.tensorflow.org/api_docs/python/tf/keras/losses/cosine_similarity
[37] https://pytorch.org/docs/stable/generated/torch.nn.CosineEmbeddingLoss.html
[1] https://www.tensorflow.org/api_docs/python/tf/keras/losses/BinaryCrossentropy
[2] https://www.tensorflow.org/api_docs/python/tf/keras/losses/binary_crossentropy
[3] https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalCrossentropy
[4] https://www.tensorflow.org/api_docs/python/tf/keras/losses/categorical_crossentropy
[5] https://www.tensorflow.org/api_docs/python/tf/keras/losses/SparseCategoricalCrossentropy
[6] https://www.tensorflow.org/api_docs/python/tf/keras/losses/sparse_categorical_crossentropy
[7] https://pytorch.org/docs/stable/generated/torch.nn.BCELoss.html
[8] https://pytorch.org/docs/stable/generated/torch.nn.BCEWithLogitsLoss.html
[9] https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html
[10] https://www.tensorflow.org/api_docs/python/tf/keras/losses/KLD
[11] https://www.tensorflow.org/api_docs/python/tf/keras/losses/KLDivergence
[12] https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html
[13] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MAE
[14] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanAbsoluteError
[15] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanAbsolutePercentageError
[16] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MAPE
[17] https://www.tensorflow.org/api_docs/python/tf/keras/losses/Huber
[18] https://pytorch.org/docs/stable/generated/torch.nn.L1Loss.html
[19] https://pytorch.org/docs/stable/nn.functional.html?highlight=loss#torch.nn.functional.l1_loss
[20] https://pytorch.org/docs/stable/generated/torch.nn.SmoothL1Loss.html
[21] https://pytorch.org/docs/stable/nn.functional.html?highlight=loss#torch.nn.functional.smooth_l1_loss
[22] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanSquaredError
[23] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MSE
[24] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MeanSquaredLogarithmicError
[25] https://www.tensorflow.org/api_docs/python/tf/keras/losses/MSLE
[26] https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html
[27] https://pytorch.org/docs/stable/nn.functional.html?highlight=loss#torch.nn.functional.mse_loss
[28] https://www.tensorflow.org/api_docs/python/tf/keras/losses/CategoricalHinge
[29] https://www.tensorflow.org/api_docs/python/tf/keras/losses/categorical_hinge
[30] https://www.tensorflow.org/api_docs/python/tf/keras/losses/Hinge
[31] https://www.tensorflow.org/api_docs/python/tf/keras/losses/hinge
[32] https://www.tensorflow.org/api_docs/python/tf/keras/losses/SquaredHinge
[33] https://www.tensorflow.org/api_docs/python/tf/keras/losses/squared_hinge
[34] https://pytorch.org/docs/stable/generated/torch.nn.HingeEmbeddingLoss.html
[35] https://www.tensorflow.org/api_docs/python/tf/keras/losses/CosineSimilarity
[36] https://www.tensorflow.org/api_docs/python/tf/keras/losses/cosine_similarity
[37] https://pytorch.org/docs/stable/generated/torch.nn.CosineEmbeddingLoss.html
推荐阅读