【问题标题】:why does the Accuracy decrease when using a ReLu activation after Linear layers为什么在线性层之后使用 ReLu 激活时精度会降低
【发布时间】:2020-01-22 19:05:43
【问题描述】:

所以我开始使用 Pytorch,并在 FashionMNIST 数据集上构建了一个非常基本的 CNN。我在使用 NN 时注意到一些奇怪的行为,但我不知道为什么会发生这种情况,在 Forward Function 中,当我在每个线性层之后使用 Relu 函数时,NN 的准确性会降低。

这是我的自定义 NN 的代码:

# custom class neural network 
class FashionMnistClassifier(nn.Module):
  def __init__(self, n_inputs, n_out):
    super().__init__()
    self.cnn1 = nn.Conv2d(n_inputs, out_channels=32, kernel_size=5).cuda(device)
    self.cnn2 = nn.Conv2d(32, out_channels=64, kernel_size=5).cuda(device)
    #self.cnn3 = nn.Conv2d(n_inputs, out_channels=32, kernel_size=5)
    self.fc1 = nn.Linear(64*4*4, out_features=100).cuda(device)
    self.fc2 = nn.Linear(100, out_features=n_out).cuda(device)
    self.relu = nn.ReLU().cuda(device)
    self.pool = nn.MaxPool2d(kernel_size=2).cuda(device)
    self.soft_max = nn.Softmax().cuda(device)

  def forward(self, x):
    x.cuda(device)
    out = self.relu(self.cnn1(x))
    out = self.pool(out)
    out = self.relu(self.cnn2(out))
    out = self.pool(out)
    #print("out shape in classifier forward func: ", out.shape)
    out = self.fc1(out.view(out.size(0), -1))
    #out = self.relu(out) # if I uncomment these then the Accuracy decrease from 90 to 50!!!
    out = self.fc2(out)
    #out = self.relu(out) # this too
    return out

n_batch = 100
n_outputs = 10
LR = 0.001

model = FashionMnistClassifier(1, 10).cuda(device)
optimizer = optim.Adam(model.parameters(), lr=LR)
criterion = nn.CrossEntropyLoss()

因此,如果我仅在 CNN 层之后使用 ReLu,我的准确度为 90%,但是当我取消注释该部分并在线性层之后使用 Relu 激活时,准确度下降到 50%,我不知道为什么会发生这种情况因为我认为在每个线性层之后使用激活总是更好,以获得更好的分类精度。我一直认为,如果我们有分类问题,我们应该始终使用激活函数,而对于线性回归,我们不必这样做,但在我的情况下,虽然这是一个分类问题,但如果我不这样做,我会得到更好的性能不要在线性层之后使用激活函数。有人可以向我澄清一下吗?

【问题讨论】:

  • 请说明您的实验是否同时添加/删除 both ReLU;正如在下面的答案中正确指出的那样,第二个 ReLU 绝对应该在那里,但原则上只保留第一个应该没问题

标签: python machine-learning neural-network deep-learning pytorch


【解决方案1】:

CrossEntropyLoss 要求您传入非标准化的 logits(来自最后一个 Linear 层的输出)。

如果你使用ReLU 作为最后一层的输出,你只会输出[0, inf) 范围内的值,而神经网络往往会为不正确的标签使用较小的值,而为正确的标签使用较高的值(我们可以说它是对它的预测过于自信)。哦,logit 值最高的那个被argmax 选为正确的标签。

所以它肯定不会与这条线一起工作:

# out = self.relu(out) # this too

虽然它应该在它之前加上ReLU。请记住,更多的非线性并不总是对网络有利。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    相关资源
    最近更新 更多