pytorch学习(五)——损失函数

news/2024/7/8 0:27:19

文章目录

  • 1. 回归问题
    • 1.1 均方差
    • 1.2 L1损失
    • 1.3 平滑L1损失
  • 2. 分类问题
    • 2.1 合页损失
    • 2.2 二分类交叉熵
    • 2.3 交叉熵
  • 3. 相似度
    • 3.1 余弦相似度
    • 3.2 相对熵
  • 4. 不配合的使用

1. 回归问题

1.1 均方差

均方差是回归问题中最常用的损失函数了,Pytorch中的均方差损失函数为

torch.nn.MSELoss(prediction, target)

设训练集中的值为 y i y_i yi,预测得到的值为 y ^ i \hat{y}_i y^i,那么二者的均方差计算为:
M S E = 1 N ∑ i = 1 N ( y i − y ^ i ) 2 MSE=\frac{1}{N} \sum_{i=1}^N (y_i-\hat{y}_i)^2 MSE=N1i=1N(yiy^i)2
适用场景
由于MSE需要对目标值进行平方,所以含有异常值时偏离会比较大,该情况不建议用MSE。

代码示范

loss = nn.MSELoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
output = loss(input, target)
print(output)

1.2 L1损失

Pytorch中的均方差损失函数为

torch.nn.L1Loss(input, target)

设训练集中的值为 y i y_i yi,预测得到的值为 y ^ i \hat{y}_i y^i,那么二者的均方差计算为:
L 1 = 1 N ∑ i = 1 N ∣ y i − y ^ i ∣ L1=\frac{1}{N} \sum_{i=1}^N \vert y_i-\hat{y}_i \vert L1=N1i=1Nyiy^i
适用场景
当目标变量含有较多的异常值时,L1损失具有很强的鲁棒性,这种情况下推荐使用L1损失。

代码示范

loss = nn.L1Loss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
output = loss(input, target)
print(output)

1.3 平滑L1损失

Pytorch中的平滑L1损失函数为

torch.nn.SmoothL1Loss(input, target)

设训练集中的值为 y i y_i yi,预测得到的值为 y ^ i \hat{y}_i y^i,那么二者的均方差计算为:
l o s s ( y , y ^ ) = 1 n ∑ i = 1 N z i loss(y,\hat{y})=\frac{1}{n}\sum_{i=1}^Nz_i loss(y,y^)=n1i=1Nzi其中,
z i = { 0.5 ( y i − y ^ i ) 2 , ∣ y i − y ^ i ∣ < 1 ∣ y i − y ^ i ∣ − 0.5 , o t h e r w i s e \begin{equation} z_i= \left\{ \begin{aligned} %\nonumber &0.5(y_i-\hat{y}_i)^2,&\vert y_i - \hat{y}_i \vert <1 \notag \\ &\vert y_i - \hat{y}_i \vert -0.5, &otherwise \notag \\ \end{aligned} \right. \end{equation} zi={0.5(yiy^i)2,yiy^i0.5,yiy^i<1otherwise
适用场景
相当于L1Loss和L2Loss的结合,拥有两者的部分有点。可以有效的避免梯度爆炸。大多数的回归类问题都可以使用,尤其是特征值中有大特征的时候。

代码示范

loss = nn.SmoothL1Loss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
output = loss(input, target)
print(output)

2. 分类问题

2.1 合页损失

合页损失函数是针对二分类的,且假设二分类的标签为 y ∈ { 1 , − 1 } y \in \{1,-1\} y{1,1}。Pytorch中的余弦相似度损失函数为

torch.nn.HingeEmbeddingLoss(y, target, margin=1)

其中 y y y 为预测得到的类别, t a r g e t target target 为样本本来的概率。

y i y_i yi 为样本的类别, y ^ i \hat{y}_i y^i 为样本预测的概率,合页损失函数可以表示为:
h i n g e ( y ^ i , y i ) = max ⁡ ( 0 , m a r g i n − y ^ i y i ) \begin{equation} hinge(\hat{y}_i,y_i)=\max(0,margin-\hat{y}_iy_i) \notag \end{equation} hinge(y^i,yi)=max(0,marginy^iyi)这个函数怎么理解呢,我们分情况讨论就很清楚了。

  1. y i > 0 , y ^ i > 0 y_i >0,\hat{y}_i>0 yi>0,y^i>0,这种情况是肯定分类正确的,但是该函数会对置信值比较低的预测值也进行惩罚,比如预测概率为 0.1 0.1 0.1,那么这个时如果 m a r g i n = 1 margin=1 margin=1,就会惩罚 0.9 0 .9 0.9,可以看到,置信值越高惩罚越小。
  2. y i < 0 , y ^ i < 0 y_i <0,\hat{y}_i<0 yi<0,y^i<0,这种情况也是肯定分类正确的,同样会对置信值低的进行惩罚。
  3. y i < 0 , y ^ i > 0 y_i <0,\hat{y}_i>0 yi<0,y^i>0,这种情况很明显分类错误,所以 y ^ i y i > 0 \hat{y}_iy_i>0 y^iyi>0,会对其进行一个比较大的惩罚。
  4. y i > 0 , y ^ i < 0 y_i >0,\hat{y}_i<0 yi>0,y^i<0,这种情况很明显分类错误,所以 y ^ i y i > 0 \hat{y}_iy_i>0 y^iyi>0,会对其进行一个比较大的惩罚。

Pytorch中使用的合页损失函数如下:
h i n g e ( y , y ^ ) = { y ^ , y = 1 m a x ( 0 , m a r g i n − ∣ y ^ ∣ ) , y = − 1 \begin{equation} hinge(y,\hat{y})= \left\{ \begin{aligned} %\nonumber &\hat{y},&y&=1 \notag \\ &max(0,margin-\vert \hat{y} \vert), &y&=-1 \notag \\ \end{aligned} \right. \end{equation} hinge(y,y^)={y^,max(0,marginy^),yy=1=1

可以看到当 y y y 为正类时,模型输出负值会有较大的惩罚,当模型输出为正值且在 ( 0 , m a r g i n ) (0,margin) (0,margin) 区间时还会有一个较小的惩罚。即合页损失不仅惩罚预测错的,并且对于预测对了但是置信度不高的也会给一个惩罚,只有置信度高的才会有零损失。使用合页损失直觉上理解是要找到一个决策边界,使得所有数据点被这个边界正确地、高置信地被分类。

适用场景
适用于二分类, l a b e l ∈ { − 1 , 1 } label \in \{-1,1\} label{1,1}

代码示范

loss_f = nn.HingeEmbeddingLoss()
inputs = torch.tensor([[1., 0.8, 0.5]])
target = torch.tensor([[1, 1, -1]])
output = loss_f(inputs,target)
print(output)

2.2 二分类交叉熵

二分类交叉熵损失函数是针对二分类的,且假设二分类的标签为 y ∈ { 1 , 0 } y \in \{1,0\} y{1,0}。Pytorch中的二分类交叉熵损失函数为

torch.nn.BCELoss(x1, x2)

计算公式如下所示:
B C E = − y log ⁡ ( y ^ ) − ( 1 − y ) log ⁡ ( 1 − y ^ ) BCE=-y \log(\hat{y})-(1-y) \log(1- \hat{y}) BCE=ylog(y^)(1y)log(1y^)其中 y y y 为真实标签, y ^ \hat{y} y^ 为预测的概率值。

适用场景
适用于二分类, l a b e l ∈ { 0 , 1 } label \in \{0,1\} label{0,1}

代码示范

m = nn.Sigmoid()
loss = nn.BCELoss()
input = torch.randn(3, requires_grad=True)
# 生成三个或0或1的数
target = torch.empty(3).random_(2)
# 因为概率是正数,所以通过一个sigmoid层将生成数据变为正数
output = loss(m(input), target)
print(output)

2.3 交叉熵

该交叉熵损失函数是计算多分类的,二分类交叉熵是其一种特殊的形式。交叉熵主要是用来判定实际的输出与期望的输出的接近程度,Pytorch中的交叉熵损失函数为

torch.nn.CrossEntropyLoss(y, target)

一般的交叉熵计算公式为
C r o s s E n t r o p y = − ∑ ( y log ⁡ ( y ^ ) + ( 1 − y ) log ⁡ ( 1 − y ^ ) ) CrossEntropy=- \sum({y} \log(\hat{y})+(1-{y}) \log(1-\hat{y})) CrossEntropy=(ylog(y^)+(1y)log(1y^))Pytorch 中为了简化计算量,使用的是另一种交叉熵函数,即
C r o s s E n t r o p y = − ∑ y ^ log ⁡ ( y ) CrossEntropy=- \sum\hat{y} \log({y}) CrossEntropy=y^log(y)
适用场景
适用于二分类与多分类。

代码示范

loss = nn.CrossEntropyLoss()
input = torch.randn(3, 5, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(input, target)
print(output)

3. 相似度

3.1 余弦相似度

Pytorch中的余弦相似度损失函数为

torch.nn.CosineEmbeddingLoss(x1, x2, target, margin=0)

常常用于评估两个向量的相似性,两个向量的余弦值越高,则相似性越高。

设传入的数据为 x 1 , x 2 x1,x2 x1,x2,传入的标签值为 y y y,那么二者的余弦相似度计算为:
l o s s ( x 1 , , x 2 , y ) = { 1 − c o s ( x 1 , x 2 ) , y = 1 m a x ( 0 , c o s ( x 1 , x 2 ) − m a r g i n ) , y = − 1 \begin{equation} loss(x1,,x2,y)= \left\{ \begin{aligned} %\nonumber &1-cos(x1,x2),&y&=1 \notag \\ &max(0,cos(x1,x2)-margin), &y&=-1 \notag \\ \end{aligned} \right. \end{equation} loss(x1,,x2,y)={1cos(x1,x2),max(0,cos(x1,x2)margin),yy=1=1其中,
c o s ( A , B ) = A ⋅ B ∥ A ∥ ∥ B ∥ = ∑ i = 0 n A i × B i ∑ i = 0 n ( A i ) 2 × ∑ i = 0 n ( B i ) 2 \begin{aligned} cos(A,B)&=\frac{A \cdot B}{\Vert A \Vert\Vert B \Vert} \notag \\ \notag \\ &=\frac{\sum_{i=0}^n A_i \times B_i}{\sqrt{\sum_{i=0}^n (A_i)^2} \times \sqrt{\sum_{i=0}^n (B_i)^2} } \end{aligned} cos(A,B)=A∥∥BAB=i=0n(Ai)2 ×i=0n(Bi)2 i=0nAi×Bi

  • y = 1 y=1 y=1的时候,就是直接用 − c o s ( x 1 , x 2 ) -cos(x1,x2) cos(x1,x2) 的平移函数作为损失函数
  • y = − 1 y=-1 y=1的时候,在 c o s ( x 1 , x 2 ) = m a r g i n cos(x1,x2)=margin cos(x1,x2)=margin 处做了分割,用于衡量两个向量的不相似性

Pytorch中支持自己设置 m a r g i n margin margin,其值在 [ − 1 , 1 ] [-1,1] [1,1],一般的 m a r g i n margin margin设置在 [ 0 , 0.5 ] [0,0.5] [0,0.5]
适用范围
计算坐标距离的相似性。

代码示范

loss = nn.CosineEmbeddingLoss()
inputs_1 = torch.tensor([[0.3, 0.5, 0.7], [0.3, 0.5, 0.7]])
inputs_2 = torch.tensor([[0.1, 0.3, 0.5], [0.1, 0.3, 0.5]])
target = torch.tensor([[1, -1]], dtype=torch.float)
output = loss(inputs_1,inputs_2,target)
print(output)

3.2 相对熵

相对熵又称KL散度,用来描述两个概率分布的差异,表示为 D ( P ∥ Q ) D(P \Vert Q) D(PQ)。在信息论中,它是用来度量使用基于Q分布的编码来编码来自P分布的样本平均所需的额外的比特个数。在机器学习领域,是用来度量两个函数的相似程度或者相近程度。

Pytorch中的相对熵API为

torch.nn.KLDivLoss(P, Q)

离散型的相对熵计算公式如下所示:
D ( P ∥ Q ) = ∑ ( P ( i ) × [ log ⁡ ( P ( i ) Q ( i ) ) ] ) = ∑ ( P ( i ) [ log ⁡ ( P ( i ) ) − log ⁡ ( Q ( i ) ) ] ) \begin{aligned} D(P \Vert Q)&=\sum (P(i) \times [\log(\frac{P(i)}{Q(i)})]) \\ &= \sum(P(i) [\log(P(i))-\log(Q(i))]) \end{aligned} D(PQ)=(P(i)×[log(Q(i)P(i))])=(P(i)[log(P(i))log(Q(i))])
适用范围
计算概率分布的相似性 。

代码示范

inputs = torch.tensor([[0.5, 0.3, 0.2], [0.2, 0.3, 0.5]])
target = torch.tensor([[0.9, 0.05, 0.05], [0.1, 0.7, 0.2]], dtype=torch.float)
loss = nn.KLDivLoss()
output = loss(inputs,target)
print(output)

4. 不配合的使用

M S E MSE MSE s i g m o i d sigmoid sigmoid 函数不适合配合使用。

M S E MSE MSE 的公式如下所示:
M S E = − 1 N ( y − y ^ ) 2 MSE=-\frac{1}{N}(y-\hat{y})^2 MSE=N1(yy^)2
如果其与 s i g m o i d sigmoid sigmoid 函数一起配合使用,偏导数则为
∂ L o s s i ∂ w = ( y − y ^ ) σ ′ ( w x i + b ) x i \frac{\partial Loss_i}{\partial w}=(y-\hat{y}) \sigma '(wx_i+b)x_i wLossi=(yy^)σ(wxi+b)xi其中
σ ′ ( w x i + b ) = σ ( w x i + b ) ( 1 − σ ( w x i + b ) ) \sigma '(wx_i+b)=\sigma (wx_i+b) (1-\sigma (wx_i+b)) σ(wxi+b)=σ(wxi+b)(1σ(wxi+b))于是,在 σ ( w x i + b ) \sigma (wx_i+b) σ(wxi+b) 的值接近于0或者1的时候,导数都接近于0,这会导致模型的学习速度在一开始非常缓慢,所以这俩不适合配套使用。


http://lihuaxi.xjx100.cn/news/109685.html

相关文章

STM32L051之IWDG使用及注意事项

IWDG使用内部时钟LSI&#xff0c;频率约为37KHz。基本框图如下所示&#xff1a; 内部包含一个8位的分频器&#xff0c;支持4、8、16、32、64、128、256分频。 内部包含一个12位的向下计数器。 假如时钟频率为32K&#xff0c;那么&#xff0c;看门狗的最大计数时间为&#xff…

Safari Extension 扩展插件中关于权限的二三事(例如设置权限、权限类型等)

Safari Extension 扩展插件的权限相关的内容大致分为下面几个方面&#xff1a; 用户要掌控扩展&#xff08;Users are in control&#xff09; Safari Extension 扩展插件是要在用户控制下的&#xff0c;不能想干嘛就干嘛&#xff0c;因此扩展只有在用户进行互动之后才会运行…

linux内核中断实践4:软中断

前言 本次实验也是在定时器处理函数中进行的&#xff0c;修改了Interrupt.h (include\linux)和文件Softirq.c (kernel)文件&#xff0c;用来增加新的软中断。 实验结果可靠&#xff0c;没问题。 如果使用硬件中断的话需要配置设备树&#xff0c;然后从设备树获取irq号&…

Linux LCD屏幕驱动调参实操

Linux LCD屏幕驱动调参实操 初探 Linux下的 LCD 驱动文中提到过&#xff0c; IMX6ULL的 eLCDIF接口驱动程序已经有半导体厂家NXP编写好了&#xff0c;并且不同分辨率LCD屏的eLCDIF接口驱动代码都是一样的&#xff0c;因此LCD驱动部分无需修改。只需要根据所使用的LCD来调整设备…

RocketMQ5.0 Broker主备自动切换模式消息不丢失部署方案

RocketMQ5.0主备自动切换模式下消息的不丢失方案如何进行部署&#xff1f;下面就来看一下 1. 下载RocketMQ5.0 首先我们去官网将RocketMQ5.0的版本下载下来。 $ wget https://dlcdn.apache.org/rocketmq/5.0.0/rocketmq-all-5.0.0-bin-release.zip 复制代码 下载完成后解压到…

React路由动画切换

目录 1.下载 2.配置 3.引入css 4.结合animate库 1.下载 cnpm install react-transition-group --save 2.配置 在路由配置文件/src/App.js文件下中导入动画组件 引入 import {TransitionGroup, CSSTransition} from react-transition-group 在路由组件模板中&#xff…

字节跳动后端面经(16)

redis主从是怎么做的 redis里面的字符串底层是什么结构 redis里的整型&#xff1f; Redis的跳表 缓存雪崩&#xff0c;缓存击穿&#xff0c;缓存穿透 mysql范围查询是怎么实现的&#xff1f; 什么是共享锁&#xff1f; 联合索引是什么&#xff1f;为什么会索引失效&#xff1f;…

为什么企业们更偏好使用华为云CDN?

互联网已经成为我们生活的基础&#xff0c;我们的生活离开不了服务器&#xff0c;数据库&#xff0c;企业更离不开&#xff0c;我们现在只要想到吃穿住喝&#xff0c;就会马上想到各种app&#xff0c;先在软件上游览一番&#xff0c;然后选择自己心仪的产品或商品下单&#xff…