赞
踩
1.先说结论
nn.BCEWithLogitsLoss
等于nn.BCELoss
+nn.Sigmoid
。
主要用于二分类问题,多标签分类问题。
图为Pytorch Document对于BCEWithLogitsLoss
的描述,这个损失函数结合了Sigmoid和BCELoss。
2.公式分解
BCEWithLogitsLoss
假设有N个batch,每个batch预测n个标签,则Loss为:
L
o
s
s
=
{
l
1
,
.
.
.
,
l
N
}
,
l
n
=
−
[
y
n
⋅
log
(
σ
(
x
n
)
)
+
(
1
−
y
n
)
⋅
log
(
1
−
σ
(
x
n
)
)
]
Loss = \{ l_1 , ... , l_N \} , \ l_n = - [ y_n \cdot \log ( \sigma { ( x_n ) }) + ( 1 - y_n ) \cdot \log ( 1 - \sigma { ( x_n ) } ) ]
Loss={l1,...,lN}, ln=−[yn⋅log(σ(xn))+(1−yn)⋅log(1−σ(xn))]
其中
σ
(
x
n
)
σ(x_n)
σ(xn)为Sigmoid
函数,可以把x映射到(0, 1)的区间:
σ
(
x
)
=
1
1
+
exp
(
−
x
)
\sigma ( x ) = \frac { 1 } { 1 + \exp ( -x ) }
σ(x)=1+exp(−x)1
BCELoss
同样假设有N个batch,每个batch预测n个标签,则Loss为:
L
o
s
s
=
{
l
1
,
.
.
.
,
l
N
}
,
l
n
=
−
[
y
n
⋅
log
(
x
n
)
+
(
1
−
y
n
)
⋅
log
(
1
−
x
n
)
]
Loss = \{ l_1 , ... , l_N \} , \ l_n = - [ y_n \cdot \log ( x_n ) + ( 1 - y_n ) \cdot \log ( 1 - x_n ) ]
Loss={l1,...,lN}, ln=−[yn⋅log(xn)+(1−yn)⋅log(1−xn)]
可见与BCEWithLogitsLoss
差了一个
σ
(
x
)
\sigma(x)
σ(x)函数
3.实验代码
# 随机初始化label值,两个Batch,每个含3个标签 label = torch.empty((2, 3)).random_(2) # 注意这是多标签问题,因此每个样本可能同时对应多种标签 # 每个标签内则是二分类问题,属于或者不属于这个标签 # tensor([[0., 1., 0.], # [0., 1., 1.]]) # 随机初始化x值,代表模型的预测值 x = torch.randn((2, 3)) # tensor([[-0.6117, 0.1446, 0.0415], # [-1.5376, -0.2599, -0.9680]]) sigmoid = nn.Sigmoid() x1 = sigmoid(x) # 归一化至 (0, 1)区间 # tensor([[0.3517, 0.5361, 0.5104], # [0.1769, 0.4354, 0.2753]]) bceloss = nn.BCELoss() bceloss(x1, label) # tensor(0.6812) # 再用BCEWithLogitsLoss计算,对比结果 bce_with_logits_loss = nn.BCEWithLogitsLoss() bce_with_logits_loss(x, label) # tensor(0.6812)
4.log-sum-exp数值稳定
当我们使用BCEWithLogitsLoss
损失函数时,除了相比于BCELoss
更方便外,还因整合了Sigmoid
函数,以实现LogSumExp的技巧,达到数值稳定的优势。
但经过测试,单纯使用Sigmoid
+BCELoss
也并没有出现
inf
\inf
inf和
−
inf
-\inf
−inf的溢出情况,还望小伙伴指点。
x = torch.tensor(1e+10)
x1 = sigmoid(x)
# tensor(1.)
label = torch.tensor(1.)
bceloss(x1, label)
# tensor(0.)
bce_with_logits_loss(x, label)
# tensor(0.)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。