训model嘛,损失函数总是要得。这里简单归纳一下常见的损失函数及其在Pytorch中的使用方法,以便查阅👨💻。
交叉熵常用于多分类任务,在Pytorch中使用torch.nn.CrossEntropyLoss()函数实现。底层地,该函数是由nn.LogSoftmax()
函数和nn.NLLLoss()
函数结合得到的。
很简单的,nn.LogSoftmax()
就是在Softmax()的基础上取对数(ln,以e为底)。
nn.NLLLoss()
即负对数似然函数(negative log likelihood loss),常用于处理K分类问题。该损失函数的输入是对数概率向量和类别标签,适合最后一层是nn.LogSoftmax()
的网络。
参考下述代码中loss1及loss2的计算方法去理解:nn.NLLLoss()
就是将nn.LogSoftmax()
输出中与label对应的值拿出来,去掉负号,再取均值。
以3张图片的5分类任务为例,我们假设label为0,2,4,我们将第一张图片网络输出五个值中的第一个值(index=0)、第二张图片输出的第三个值(index=2)、第三张图片输出的第五个值(index=4)拿出来,将这个三个数取相反数,求平均值,即为负对数似然函数的输出。
import torch
import torch.nn as nn
inputs = torch.randn(3, 5)
label = torch.tensor([0, 2, 4])
print(inputs)
'''
tensor([[-4.0413e-01, -2.3209e+00, 7.4667e-01, -1.5884e-01, -9.4237e-01],
[ 9.7085e-02, 6.3694e-02, -1.7933e-01, 2.6058e-01, -1.9870e-01],
[ 1.0408e-01, 5.2098e-05, -9.9802e-01, -2.0989e-01, 1.1665e+00]])
'''
log_softmax = nn.LogSoftmax(dim=1)
net = log_softmax(inputs)
print(net)
'''
tensor([[-1.8196, -3.7364, -0.6688, -1.5743, -2.3579],
[-1.5363, -1.5697, -1.8127, -1.3728, -1.8321],
[-1.7677, -1.8717, -2.8698, -2.0817, -0.7052]])
'''
# NLLLoss after LogSoftmax.
nll = nn.NLLLoss()
loss1 = nll(net, label)
print('NLLLoss value after LogSoftmax layer is {}.'.format(loss1))
# 1.4459
# Simulink the process of NLLLoss.
loss2 = 0.
for i in range(len(label)):
loss2 += net[i][label[i]]
loss2 = (-1.0) * loss2 / len(label)
print("Simulink the process of NLLLoss to get loss: {}.".format(loss2))
# 1.4459
# CrossEntropyLoss: combination of Softmax, log and NLLLoss.
ce = nn.CrossEntropyLoss()
loss3 = ce(inputs, label)
print("Loss from CrossEntropyLoss is {}.".format(loss3))
# 1.4459