pytorch MNIST 神经网络产生几个非零输出

pytorch MNIST neural network produces several non-zero outputs

我尝试做一个在 MNIST 数据集上运行的神经网络。我主要是在遵循 pytorch.nn 教程。结果,我得到了一个可以学习的模型,但是过程或模型本身有问题。我在输出端收到了多个神经元,而不是一个活跃的神经元。

这是模型本身:

model = nn.Sequential(
    nn.Linear(784, 64),
    nn.ReLU(),
    nn.Linear(64, 10),
    nn.ReLU(),
)

这是训练过程:

loss_func = nn.CrossEntropyLoss()
opt = optim.SGD(model.parameters(), lr=lr)

for epoch in range(epochs):
    model.train()
    for xbt, ybt in train_dl:
        pred = model(xbt)
        loss = loss_func(pred, ybt)
        opt.zero_grad()
        loss.backward()
        opt.step()
        

    model.eval()
    # Validation
    if epoch % 10 == 0:
        with torch.no_grad():
            losses, nums = zip(
                *[(loss_func(model(xbv), ybv), len(xbv)) for xbv, ybv in valid_dl]
            )
        val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)

        print(epoch, val_loss)

这是每 10 个周期的平均损失:

0 0.13384412774592638
10 0.0900113809091039
20 0.09795805384699234
30 0.10341344920364791
40 0.10804545368137551

这就是将模型应用于验证集的结果:

[[ 0.         0.         0.        ... 28.436266   0.         5.001435 ]
 [ 7.3331523 12.666427  31.898096  ...  0.         0.         0.       ]
 [ 0.        18.116354   8.049953  ...  4.330721   0.         0.       ]
 ...
 [ 8.504517   0.         6.302228  ...  0.         0.         0.       ]
 [ 1.7339934  0.         0.        ...  0.         2.1565871  0.       ]
 [45.750134   0.         6.2685804 ...  2.247082   0.         0.       ]]
 Shape: (9984, 10)

我尝试更改学习速度、模型层数、迭代次数,但似乎没有任何效果。

这是绝对正常的: 你的输出应该是 [bacth_size, 10] 的形状,因为在每次迭代中你给它输入一批 batch_size 图像并且输出层有 10 个神经元。

解读方式如下:

  • 输出张量的每一行都是对批次中一张输入图像的预测。
  • 对于一行,如果你只想classify,你的猜测将是该行的argmax。例如,如果 output[0] = [ 0. , 0. , 0. , 2.1, 3.0, 0., 4., 28.436266 0., 5.001435 ],则表示您的网络预测该图像属于 class n°7(28.436266 是最大值,在索引 7 处)。

现在,您还可以使用某种概率来解释结果。为此,您需要对输出应用 softmax 图层。然后值 output[i][j] 将被解释为图像 i 属于 class j.

的概率

最后一层有 10 个带有 ReLU 的神经元,是的,所有神经元都会 fire/activated。在这种情况下,每个神经元对线性激活的输出应用 ReLu 函数。即ReLu(w.x+b)。有 10 个这样的神经元,它们都会根据其输入给出一定的输出,是的,它们都会得到 fired/activated。从中推断输出的方法是采用与具有最大激活的神经元对应的 class(使用 np.argmax 或 torch.max)。