почему точность уменьшается при использовании активации ReLu после линейных слоев - PullRequest
0 голосов
/ 22 сентября 2019

поэтому я начал использовать Pytorch и создаю очень простой CNN для набора данных FashionMNIST.Я заметил какое-то странное поведение при использовании NN, и я не знаю, почему это происходит, в функции Forward точность NN уменьшается, когда я использую функцию Relu после каждого линейного слоя.

вот код для моего пользовательского 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()

, поэтому, если я использую ReLu только после слоев CNN, я получаю точность 90%, но когда я раскомментирую этот раздел и используюАктивация Relu после линейных слоев. Точность снижается до 50%. Я понятия не имею, почему это происходит, поскольку я думал, что всегда лучше использовать активацию после каждого линейного слоя, чтобы получить более высокую точность классификации.Я всегда думал, что мы всегда должны использовать функцию активации, если у нас есть проблема классификации, и для линейной регрессии нам не нужно это делать, но здесь, в моем случае, хотя это проблема классификации, я получаю лучшую производительность, если я надеваюне использовать функцию активации после линейных слоев.Может быть, кто-то объяснит мне это?

1 Ответ

2 голосов
/ 22 сентября 2019

CrossEntropyLoss требует, чтобы вы передавали ненормализованные логиты (вывод из последнего Linear слоя).

Если вы используете ReLU в качестве вывода из последнего слоя, вы выводите только значения в диапазоне [0, inf), в то время как нейронная сеть имеет тенденцию идти с маленькими значениями для неправильных меток и высокими для правильных (мы можем сказать, что она слишком уверена в своих предсказаниях).Да, и тот, который имеет наибольшее значение логита, выбирается argmax в качестве правильной метки.

Так что он точно не будет работать с этой строкой:

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

Хотя это должно быть сReLU до этого.Просто помните, что больше нелинейности не всегда хорошо для сети.

...