文章目录
- 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=1∑N(yi−y^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=1∑N∣yi−y^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=1∑Nzi其中,
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(yi−y^i)2,∣yi−y^i∣−0.5,∣yi−y^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,margin−y^iyi)这个函数怎么理解呢,我们分情况讨论就很清楚了。
- 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,可以看到,置信值越高惩罚越小。
- y i < 0 , y ^ i < 0 y_i <0,\hat{y}_i<0 yi<0,y^i<0,这种情况也是肯定分类正确的,同样会对置信值低的进行惩罚。
- 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,会对其进行一个比较大的惩罚。
- 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,margin−∣y^∣),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^)−(1−y)log(1−y^)其中
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^)+(1−y)log(1−y^))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)={1−cos(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∥∥B∥A⋅B=∑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(P∥Q)。在信息论中,它是用来度量使用基于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(P∥Q)=∑(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(y−y^)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
∂w∂Lossi=(y−y^)σ′(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,这会导致模型的学习速度在一开始非常缓慢,所以这俩不适合配套使用。