深度学习常用损失函数详解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

机器学习任务大概可以分为两类问题,分别是回归问题和分类问题。回归问题预测的是一个连续的数值,例如房价,气温等。而分类问题是将输入预测为不同的类别,例如猫狗分类等。总的来说,回归问题输出是一个实数范围,可以是任何数值;分类问题输出是离散的类别标签,通常是整数或特定的类别名称。接下来对回归问题和分类问题常用的损失函数进行介绍。

一、回归问题

1. 均方误差(MSE)

 MSE损失(Mean Squared Error)也称为 L 2 L_2 L2 Loss,是回归问题中比较常用的损失函数。其公式为:

L M S E ( y , y ^ ) = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 L_{MSE}(y,\hat{y}) = \frac{1}{n}\sum_{i=1}^n(y_i-\hat{y}_i)^2 LMSE(y,y^)=n1i=1n(yiy^i)2

其中, y y y为模型的预测值, y ^ \hat{y} y^为标签值。
 优点:由于平方操作,MSE对较大的误差给予更大的惩罚,这有助于模型学习减少大的预测偏差。
 缺点:MSE对异常值或离群点非常敏感,这可能会影响模型的泛化能力。
代码实现:

import torch
import torch.nn as nn

y = torch.Tensor([1,2,3])
label = torch.Tensor([3,5,1])
criterion = nn.MSELoss()
loss = criterion(y,label)
print(loss)

输出为tensor(5.6667)

2. 均方根误差 (RMSE)

 RMSE误差(Root Mean Squared Error)的公式为:

L M S E ( y , y ^ ) = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 L_{MSE}(y,\hat{y}) = \sqrt{\frac{1}{n}\sum_{i=1}^n(y_i-\hat{y}_i)^2} LMSE(y,y^)=n1i=1n(yiy^i)2

其相当于在MSE的基础上加了一个根号。
 优点:与MSE一样,RMSE对较大的误差给予更大的惩罚,同时因为开根号的缘故,它的单位与原始数据的单位相同,这使得它在解释预测误差时更加直观。
 缺点:对异常值或离群点非常敏感,计算量较大,RMSE比较难优化,因为它不是一个严格凸函数。

3. 平均绝对误差 (MAE)

 MAE(Mean Absolute Error)又称为 L 1 L_1 L1 Loss,计算所有样本预测值与实际值之差的绝对值的平均值。公式为:

L M A E ( y , y ^ ) = 1 n ∑ i = 1 n ∣ ( y i − y ^ i ) ∣ L_{MAE}(y,\hat{y}) = \frac{1}{n}\sum_{i=1}^n|(y_i-\hat{y}_i)| LMAE(y,y^)=n1i=1n(yiy^i)

其中, y y y为预测值, y ^ \hat{y} y^为标签值。
 优点:对异常值不敏感,单位与原始数据一致,易于直观理解,计算简单。
 缺点:可能不利于模型学习减少较大的预测偏差。
代码实现:

import torch
import torch.nn as nn

y = torch.Tensor([1,2,3])
label = torch.Tensor([3,5,1])
criterion = nn.L1Loss()
loss = criterion(y,label)
print(loss)

输出为tensor(2.3333)

二、分类问题

1. 相关概念

 首先我们先介绍一下相关概念。
信息熵:用来衡量信息的不确定性或信息的平均信息量。其公式为:

H ( x ) = − ∑ i = 1 n P ( x i ) log ⁡ P ( x i ) H(x) = -\sum_{i=1}^nP(x_i)\log P(x_i) H(x)=i=1nP(xi)logP(xi)

其中, P ( x i ) P(x_i) P(xi)为随机事件 x i x_i xi发生的概率。若事件发生的不确定性越大,则其熵越大,代表含有更多的信息量。
KL散度:是一种衡量一个概率分布P相对于另一个概率分布Q的非对称性差异,其公式为:

D K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) log ⁡ ( p ( x i ) q ( x i ) ) D_{KL}(p||q) = \sum_{i=1}^np(x_i)\log (\frac{p(x_i)}{q(x_i)}) DKL(p∣∣q)=i=1np(xi)log(q(xi)p(xi))

其中, p p p q q q是两种不同的分布, p ( x i ) p(x_i) p(xi) q ( x i ) q(x_i) q(xi)分别代表随机事件在 p p p q q q这两个分布中发生的概率。其具有以下特性:

非负性:KL散度总是正的
非对称性: D K L ( p ∣ ∣ q ) D_{KL}(p||q) DKL(p∣∣q)不等于 D K L ( q ∣ ∣ p ) D_{KL}(q||p) DKL(q∣∣p),只有当两个分布相等时, D K L ( p ∣ ∣ q ) = D K L ( q ∣ ∣ p ) D_{KL}(p||q)=D_{KL}(q||p) DKL(p∣∣q)=DKL(q∣∣p)
在信息论中,KL散度可以被解释为在使用概率分布Q来拟合真实分布P时产生的信息损耗。

交叉熵:用于衡量两个概率分布之间的差异,是对称的。

H ( P , Q ) = − ∑ i = 1 n p ( x i ) log ⁡ q ( x i ) = H ( P ) + D K L ( p ∣ ∣ q ) H(P,Q) = -\sum_{i=1}^np(x_i)\log q(x_i) = H(P)+D_{KL}(p||q) H(P,Q)=i=1np(xi)logq(xi)=H(P)+DKL(p∣∣q)
H ( P , Q ) = H ( Q , P ) H(P,Q)=H(Q,P) H(P,Q)=H(Q,P)

其中, p p p q q q是两个分布。交叉熵经常用作分类问题的损失函数,其中,P可以看作是标签的分布,Q可以看作是模型预测的分布。

2. 交叉熵损失函数

 交叉熵损失函数(Cross-Entropy Loss)是分类问题中常用的损失函数,其衡量的是模型预测的概率分布和标签的真实分布之间的差异。前面说过,计算两个分布之间的交叉熵公式为:

H ( P , Q ) = − ∑ i = 1 n p ( x i ) log ⁡ q ( x i ) H(P,Q) = -\sum_{i=1}^np(x_i)\log q(x_i) H(P,Q)=i=1np(xi)logq(xi)

其中, P P P为标签的分布, Q Q Q为模型预测的分布。接下来我们举一个例子来说明。

例如我们要做一个三分类[汽车,猫,飞机]的物体分类,假设标签为1,我们会将标签1转换为one-hot编码[0,1,0],然后将模型的输出经过softmax操作进行归一化将其转换为概率值,然后计算交叉熵。

分类模型预测标签
汽车0.050
0.801
飞机0.150

则公式为

L o s s = − ( 0 ∗ log ⁡ 0.05 + 1 ∗ log ⁡ 0.80 + 0 ∗ log ⁡ 0.15 ) = − log ⁡ 0.80 Loss = -(0*\log0.05 + 1*\log0.80 + 0*\log0.15)=-\log0.80 Loss=(0log0.05+1log0.80+0log0.15)=log0.80

 因为在分类问题中,标签的分布中只有一个1,其他都为0。因此,在分类问题中,交叉熵损失函数可以简化为:

L o s s = − log ⁡ p ( x i ) Loss = -\log p(x_i) Loss=logp(xi)

其中, p ( x i ) p(x_i) p(xi)为模型预测的分类结果的概率值。例如,在上述例子中 p ( x i ) p(x_i) p(xi)的值为0.80。
代码实现:

import torch
import torch.nn as nn

logits = torch.tensor([[0.68,-0.8,0.75]]) #模型的输出  
labels = torch.tensor([2])  #标签值为2 
criterion = nn.CrossEntropyLoss()
loss = criterion(logits, labels)
print(loss.item())

最终的输出结果为0.8329725861549377。

3. BCE Loss

 BCE Loss(Binary Cross-Entropy Loss)是在二分类问题中常用的损失函数,其公式为:

L B C E = − ( y ∗ log ⁡ ( p ) + ( 1 − y ) ∗ log ⁡ ( 1 − p ) ) L_{BCE} = -(y*\log(p)+(1-y)*\log(1-p)) LBCE=(ylog(p)+(1y)log(1p))

其中, y y y为标签值(0或者1), p p p为模型预测为正样本(标签值为1)的概率。在计算Loss之前,首先要将模型的输出经过Sigmoid激活函数将概率值 p p p映射到[0,1]之间。
 注意:与使用交叉熵损失做二分类不同的是,如果使用交叉熵损失,则最终模型的输出是一个向量,这个向量经过softmax操作后变成概率分布,代表是正样本的概率和负样本的概率,这些概率相加等于1;而使用BCE Loss时,模型的输出是一个数,然后经过sigmoid操作映射到[0,1]之间,映射后的值就代表模型预测该物品是正样本的概率。下面举一个例子来说明。

假设使用BCE Loss做一个二分类的问题,模型的输出为2.56,然后经过sigmoid操作映射成0.80(瞎编的),说明模型预测为正样本的概率为0.8。
如果标签是0(负样本),然后使用公式计算:
L o s s = − ( 0 ∗ log ⁡ ( 0.8 ) + 1 ∗ log ⁡ ( 0.2 ) ) = − l o g ( 0.2 ) Loss = -(0*\log(0.8) + 1*\log(0.2)) = -log(0.2) Loss=(0log(0.8)+1log(0.2))=log(0.2)
如果标签是1(正样本),然后使用公式计算:
L o s s = − ( 1 ∗ log ⁡ ( 0.8 ) + 0 ∗ log ⁡ ( 0.2 ) ) = − l o g ( 0.8 ) Loss = -(1*\log(0.8) + 0*\log(0.2)) = -log(0.8) Loss=(1log(0.8)+0log(0.2))=log(0.8)

如果使用的是交叉熵损失函数做二分类问题,标签0代表负样本,标签1代表正样本,假设经过softmax操作后的概率分布为[0.2(负样本),0.8(正样本)]
如果标签是0,转换为one-hot编码[1,0],使用交叉熵损失函数:
L o s s = − log ⁡ ( 0.2 ) Loss =-\log(0.2) Loss=log(0.2)
如果标签是1,转换为one-hot编码[0,1],使用交叉熵损失函数:
L o s s = − log ⁡ ( 0.8 ) Loss =-\log(0.8) Loss=log(0.8)

 通过上述两个例子可以看出,当做二分类任务时,BCE和交叉熵的Loss最终函数形式是一样的,个人认为,这两种损失函数主要的不同在于模型最终的输出形式和最终的概率映射方式不同。

代码实现:

import torch
import torch.nn as nn

predicted_probabilities = torch.tensor([0.8])  # 模型预测的为正样本概率
#1表示正样本,0表示负样本
true_labels = torch.tensor([1])
# 将布尔值转换为浮点数,因为PyTorch的BCELoss期望浮点数标签
true_labels = true_labels.float()
criterion = nn.BCELoss()
loss = criterion(predicted_probabilities, true_labels)
print(loss.item())

代码输出为0.2231435328722。

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值