torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction='mean', label_smoothing=0.0)
计算 logits
和 target
之间的交叉熵。
N x H x W x C
N x H x W
,每个值表示了真值类别的 index。patameters:
举个例子
import torch
import torch.nn as nn
def crossEntropyLoss(output,target):
criterion = nn.CrossEntropyLoss(reduction='mean')
return criterion(output,target)
if __name__ == "__main__":
output = torch.tensor([[5,5],[2,8]],dtype=torch.float32)
target = torch.tensor([0,1]).long()
print("cross:{}".format(crossEntropyLoss(output,target)))
torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')
计算 input
和 target
之间的二元交叉熵。只能解决二分类问题。一般与nn.sigmoid()
一起用。
patameters
举个例子
import torch
import torch.nn as nn
def bceLoss(output,target):
criterion = nn.BCELoss(reduction='mean')
output = torch.sigmoid(output)
print("output: {}".format(output))
return criterion(output,target)
if __name__ == "__main__":
output = torch.tensor([[3],[2]],dtype=torch.float32) # 每个样本属于该类的分数
targer = torch.tensor([[1],[0]],dtype=torch.float32) # ground truth
print(bceLoss(output,targer).item())
二元交叉熵作多标签分类问题(相当于多个二分类问题)
ATTENTION
在做二分类任务时,nn.CrossEntropyLoss
= torch.softmax
+ nn.BCELoss
。 但是在单个二分类任务中,torch.softmax
+ nn.BCELoss
没有什么意义。
nn.BCELoss
来说,在图像分割前景和后景时,每个样本对应的 target
为 1 或 0 ,前者表示属于前景,后者表示属于后景。(因为不属于前景的一定属于后景,所以可以用一个类别来表示)nn.CrossEntropyLoss
来说,在图像分割前景和后景时,每个样本对应的 target
为 [1,0] 或 [0,1] ,前者表示属于前景,后者表示属于后景。(虽然p(前景)+p(后景)=1
,但是必须将前景和后景分为两类来做,因为如果只用一个类别的话,那么每个像素对应的 logits
就只有一个值,这样经过 softmax
后,值永远为 1 ,模型无法收敛!)import torch
import torch.nn as nn
output = torch.tensor([[5,5],[2,8]],dtype=torch.float32) # 2x2 图像 作为输入
output = torch.softmax(output,dim=-1) # 按行进行 softmax
print(output)
target = torch.tensor([[[0,1],[1,0]]).float() # 表示个每个像素点的类别真值
bce=nn.BCELoss()
print("bce:{}".format(bce(output,target)))
# 如果用 nn.CrossEntropyLoss 计算:
'''
由于上文中 softmax 是按行来计算的,所以输入应当转换为 [[5,5],[5,5],[8,2],[2,8]]
'''
output = torch.tensor([[5,5],[5,5],[8,2],[2,8]],dtype=torch.float32)
target = torch.tensor([0,1,1,0]).long()
print("cross:{}".format(crossEntropyLoss(output,target)))
# output
tensor([[0.5000, 0.5000],
[0.0025, 0.9975]])
bce:3.347815990447998
cross:3.347811698913574
torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction='mean', pos_weight=None)
nn.BCEWithLogitsLoss = nn.sigmoid + nn.BCELoss
这个版本在数值上比使用普通 Sigmoid + BCELoss 更稳定,因为通过将操作组合到一个层中,我们利用了 log-sum-exp 技巧来实现数值稳定性。
patameters:
举个例子
output = torch.tensor([[3],[2]],dtype=torch.float32)
target = torch.tensor([[1],[0]],dtype=torch.float32)
loss2=nn.BCEWithLogitsLoss()
print("BCEWithLogitsLoss:",loss2(output,target)) # 不需要sigmoid
ATTENTION