一、二分类交叉熵的两种计算接口
torch.nn.BCELoss
和torch.nn.BCEWithLogitsLos
二、二者计算接口的区别
torch.nn.BCELoss
就是我们通常意义理解的二分类交叉熵的计算,并且提供了权重和维度的控制。 w n w_n wn表示权重控制。 r e d u c t i o n reduction reduction表示维度控制的方式。
ℓ
(
x
,
y
)
=
L
=
{
l
1
,
…
,
l
N
}
⊤
,
l
n
=
−
w
n
[
y
n
⋅
log
x
n
+
(
1
−
y
n
)
⋅
log
(
1
−
x
n
)
]
,
\ell(x, y) = L = \{l_1,\dots,l_N\}^\top, \quad l_n = - w_n \left[ y_n \cdot \log x_n + (1 - y_n) \cdot \log (1 - x_n) \right],
ℓ(x,y)=L={l1,…,lN}⊤,ln=−wn[yn⋅logxn+(1−yn)⋅log(1−xn)],
ℓ
(
x
,
y
)
=
{
mean
(
L
)
,
if reduction
=
’mean’;
sum
(
L
)
,
if reduction
=
’sum’.
\ell(x, y) = \begin{cases} \operatorname{mean}(L), & \text{if reduction} = \text{'mean';}\\ \operatorname{sum}(L), & \text{if reduction} = \text{'sum'.} \end{cases}
ℓ(x,y)={mean(L),sum(L),if reduction=’mean’;if reduction=’sum’.
需要注意:
如果
x
n
x_n
xn为0或1 ,PyTorch会设置
l
o
g
(
0
)
=
−
∞
log(0)=-\infty
log(0)=−∞,但是
−
∞
-\infty
−∞在loss计算方程中是不可取的,原因如下
- 此时将会出现0×无穷大的情况
- loss为无穷大,意味着梯度也无穷大,此时关于 x n x_n xn的反向传播将会导致非线性
因此,PyTorch在使用torch.nn.BCELoss
的时候,会将BCELoss的输出截断至大于等于-100。通过这个操作,可以获得有限的loss值以及线性的反向传播。
torch.nn.BCEWithLogitsLos
则是结合了Sigmoid和BELoss两个操作,但是并不是两个操作的简单结合。在结合的时候使用了 log-sum-exp 技巧获得了更好的数值计算稳定性