В противоположность ожидаемому поведению [PyTorch] - PullRequest
0 голосов
/ 04 мая 2020

У меня есть набор данных с серьезным дисбалансом класса (банк-дополнительный-полный). Я использую его, не внося никаких изменений, кроме присвоения значений категориальной переменной. Он имеет около 89% классов no (0) и 11% классов yes (1).

Моя модель всегда предсказывает yes (меньшее число единиц), а также изменение скорости обучения не оказывает никакого влияния. Он должен предсказать класс, который имеет большее число чаще, т. Е. Нет

Я изучаю pytorch, поэтому дайте мне знать мою ошибку, поскольку у меня возникают проблемы с ее поиском.

class LogisticRegressionModel(nn.Module):
  def __init__(self, input_dim, output_dim):
      super(LogisticRegressionModel, self).__init__()
      self.linear = nn.Linear(input_dim, output_dim)
  def forward(self, x):

      out = F.softmax(self.linear(x),dim=1)
      return out

 input_dim = 1*20 
 output_dim = 2

 model = LogisticRegressionModel(input_dim, output_dim)
 criterion = nn.CrossEntropyLoss()
 learning_rate = 0.01
 optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

 iter = 0
num_epochs= 10
train_losses, val_losses = [], []
for epoch in range(num_epochs):
  running_loss = 0
  for i, (x, labels) in enumerate(train_loader):

      x = Variable(x.view(-1, height*width))
      labels = Variable(labels)     
      optimizer.zero_grad()        
      outputs = model(x.float())       
      loss = criterion(outputs, labels)      
      loss.backward()

      optimizer.step()

      running_loss += loss.item()

      iter += 1

  else:
      val_loss = 0


      correct = 0
      total = 0
      with torch.no_grad():

          for x, labels in val_loader:

              x = Variable(x.view(-1,height*width))                             
              outputs = model(x.float())

              val_loss += criterion(outputs, labels)

              values, predicted = torch.max(outputs.data, 1)
              #print(values.data)    


              total += labels.size(0)

              correct += (predicted == labels).sum()                


      accuracy = 100 * correct / total

      train_losses.append(running_loss/len(train_loader))
      val_losses.append(val_loss/len(val_loader))

      print("Epoch: {}/{}.. ".format(epoch+1, num_epochs),
                "Training Loss: {:.3f}.. ".format(running_loss/len(train_loader)),
                "Validation Loss: {:.3f}.. ".format(val_loss/len(val_loader)),
                "Validation Accuracy: {:.3f}".format(accuracy))

      print("\n")



Результаты : Эпоха: 1/10 .. Потеря обучения: 1.201 .. Потеря проверки: 1.202 .. Точность проверки: 11.000

потери и точность остаются неизменными и не изменяются

1 Ответ

0 голосов
/ 04 мая 2020

В данном коде веса не обновляются. Если вы запустите

list(model.parameters())[0].grad

, вы получите

tensor([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

или None. Поскольку градиенты нулевые веса не обновляются.

Если вы измените F.softmax (out) на F.log_softmax (out), это решит проблему. На данный момент я не имею глубоких знаний о том, почему это происходит. Но вы можете посетить: https://discuss.pytorch.org/t/weights-never-update-while-training/8418/9

У этой ссылки есть объяснение

Редактировать:

Комментарий, данный @jodag, объясняет реальное проблема.

...