NLLLOSS 是 negative log likelihood loss 负对数似然损失函数,CROSSENTROPYLOSS 是交叉熵损失函数,它们都是用于多分类任务的损失函数,正如我在笔记中提到的,它们实际上是一样的,在 Pytorch 中这两者的区别就只在于接收的输入不同:
torch.nn.functional.cross_entropy 将 logits 作为输入(内部自动实现 log_softmax)
torch.nn.functional.nll_loss 将 log-probabilities (log-softmax) 作为输入
logits 即 log_softmax 层的输入,log-probabilities 即 Softmax 层的输出,也就是说:
CrossEntropyLoss=LogSoftmax+NLLLossCrossEntropyLoss = LogSoftmax + NLLLossCrossEntropyLoss=LogSoftmax+NLLLoss
实际代码的演示如下:
1、假设 Softmax 层的输入矩阵为 Z,其中每一行是一个训练示例:
2、将它们经过 Softmax 层,得到输出矩阵 smax
3、nll_loss 的输入为 smax 的对数,即 log_softmax;而 cross_entropy 的输入为 Z
示意图如下:
对于二分类的情况,即二元交叉熵 binary_cross_entropy 也是有两种实现:BCEWithLogitsLoss 和 BCELoss,两者区别在于接收的输入不同。具体可以看这篇博客。
正如我的笔记中写到的,PyTorch 有两种 API:函数式方法(functional)和面向对象方法(object-oriented)。面向对象方法意味着它们被实现为 Python 类,我们必须实例化对象才能使用它们。如果我们必须跟踪内部状态(如模型权重和梯度),那么面向对象的范例就很棒。
然而,对于不需要内部状态的东西,比如损失函数,我们也可以使用函数式 API,这样我们就不必再去实例化损失了。换句话说,PyTorch 的功能 API 通过 torch.nn.functional 子模块提供没有内部状态的实现。这里我们使用的也正是函数式的 API。