machine-learning - PyTorch 教程中的交叉熵计算

标签 machine-learning deep-learning pytorch cross-entropy

我正在阅读多类分类问题的 Pytorch 教程。而且我发现 Pytorch 中 Loss 计算的行为让我很困惑。你能帮我解决这个问题吗?

用于分类的模型是这样的:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

训练过程如下:

optimizer.zero_grad()
outputs = net(inputs)
loss = nn.CrossEntropyLoss(outputs, labels)
loss.backward()
optimizer.step()

我的问题是:Pytorch 中损失计算的确切行为是什么?在每次迭代中,nn.CrossEntropyLoss() 的输入有两部分:

  1. 模型的输出,它是一个 10 x 1 张量,其中包含不同的值。这是一个没有归一化为概率的张量。
  2. 作为标量的标签,例如 1 或 2 或 3。

据我所知,交叉熵的计算通常用于两个张量之间,例如:

  1. 目标为 [0,0,0,1],其中 1 是正确的类别
  2. 输出张量为 [0.1,0.2,0.3,0.4],其中总和为 1。

所以基于这个假设,这里的nn.CrossEntropyLoss()需要实现:

  1. 首先将输出张量归一化为可能性一。
  2. 将标签编码为单热标签,例如 5 类中的 2 个 [0,1,0,0,0]。长度必须与输出张量相同。
  3. 然后计算损失。

请问这是 nn.CrossEntropyLoss() 的作用吗?或者我们是否需要在输入模型之前对真实标签进行一次性编码?

非常感谢您提前抽出时间!

最佳答案

nn.CrossEntropyLoss首先应用 log-softmax (log(Softmax(x)) 获取对数概率,然后计算负对数似然,如文档中所述:

This criterion combines nn.LogSoftmax() and nn.NLLLoss() in one single class.

当使用 one-hot 编码目标时,交叉熵可以计算如下:

cross-entropy

其中 y 是单热编码目标向量,ŷ 是每个类别的概率向量。要获得概率,您可以将 softmax 应用于模型的输出。使用概率的对数,PyTorch 只是将对数和 softmax 合并为一个操作 nn.LogSoftmax() , 为了数值稳定性。

由于 one-hot 向量中除 1 之外的所有值均为零,因此总和中只有一项为非零。因此给定实际类,可以简化为:

cross-entropy simplified

只要知道类别索引,就可以直接计算损失,这比使用单热编码目标更有效,因此 nn.CrossEntropyLoss期望类索引。

完整的计算在 nn.CrossEntropyLoss 的文档中给出。 :

The loss can be described as: cross-entropy full

关于machine-learning - PyTorch 教程中的交叉熵计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62161194/

相关文章:

python - 如何解释作为最后一层 sigmoid 激活输出的深度学习模型的概率预测?

python - 升级到 PyTorch 1.9 时的潜在错误 ImportError : cannot import name 'int_classes' from 'torch._six'

machine-learning - 使用 One Hot 编码时的逻辑回归方程

python - 在 TF.Keras 中使用自定义模型进行梯度累积?

python - CountVectorizer 中的样本数量不一致

python - 如何组合和重叠两个张量?

python - PyTorch 中相同形状的掩蔽张量

python - 在 PyTorch 中,如何通过损失列表中的平均梯度更新神经网络?

r - 使用现有数据和概率模拟数据

apache-spark - Apache Spark 用户推荐?