1.先说结论
主要用于二分类问题,多标签分类问题。
图为Pytorch Document对于
2.公式分解
-
BCEWithLogitsLoss
假设有N个batch,每个batch预测n个标签,则Loss为:Loss={l1?,...,lN?}, ln?=?[yn??log(σ(xn?))+(1?yn?)?log(1?σ(xn?))]
其中σ(xn?)为
Sigmoid 函数,可以把x映射到(0, 1)的区间:σ(x)=1+exp(?x)1?
-
BCELoss
同样假设有N个batch,每个batch预测n个标签,则Loss为:Loss={l1?,...,lN?}, ln?=?[yn??log(xn?)+(1?yn?)?log(1?xn?)]
可见与BCEWithLogitsLoss 差了一个σ(x)函数
3.实验代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # 随机初始化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数值稳定
当我们使用
但经过测试,单纯使用
inf和
?inf的溢出情况,还望小伙伴指点。
1 2 3 4 5 6 7 8 9 10 | 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.) |