【问题标题】:pytorch model not updatingpytorch 模型不更新
【发布时间】:2020-05-17 15:56:47
【问题描述】:

我把我的训练代码放在下面。我正在使用 torch.optim.SGD 作为优化器。我认为 optimizer.step() 会进行更新,但模型准确性似乎保持不变。我的朋友说他没有使用 optimizer.step() 并且他的工作正常。 我试着把它拿出来,结果还是一样。我做错了什么? 我认为准确度计算没有问题。

class FNet(nn.Module):
    def __init__(self, **kwargs): 
        super().__init__()
        self.fc1 = nn.Linear(128*256, 1024) 
        self.fc2 = nn.Linear(1024, 256)
        self.fc3 = nn.Linear(256, 2)

    def forward(self, X): 
        X = F.relu(self.fc1(X))
        X = F.relu(self.fc2(X))
        X = self.fc3(X)
        return F.softmax(X, dim=1)



def main():

    learning_rate = 0.01
    model = FNet()
    optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9, weight_decay=5e-04) # you can play with momentum and weight_decay parameters as well
    accs = [0,]

    for epoch in range(max_epoch):

        train(epoch, model, optimizer, train_batch)

        acc = test(model, val_batch)
        accs.append(acc)


def train(epoch, model, optimizer, trainloader):
    model.train()
    optimizer.zero_grad()
    for batch_idx, (data, labels) in enumerate(trainloader):

        outputs = model(data)
        loss = F.nll_loss(outputs, labels)
        loss.backward()

        optimizer.step()


def test(model, testloader):
    correct = 0
    total = 0
    model.eval()

    for batch_idx, (data, labels) in enumerate(testloader):

            outputs = model(data.view(-1,128*256))

            for sample_idx,output in enumerate(outputs):

                if torch.argmax(output) == labels[sample_idx]:
                    correct = correct + 1
                total = total + 1

    accuracy = correct/total
    return accuracy

【问题讨论】:

  • 提供一小段代码并没有帮助。缺少相关信息,例如,您是否将模型参数传递给优化器?优化器需要知道要更新哪些参数。
  • 我添加了其余的运行代码。
  • 你观察到损失值有没有减少?
  • 损失值到处都是,有时下降有时又上升。我不确定发生了什么
  • 你可以在不设置动量和权重衰减和检查的情况下使用优化器吗?

标签: python pytorch training-data


【解决方案1】:

我认为这条线应该在你的 for 循环下 optimizer.zero_grad()。您需要在每次循环后清除参数梯度。

试试这个

def train(epoch, model, optimizer, trainloader):
    model.train()
    for batch_idx, (data, labels) in enumerate(trainloader):
        optimizer.zero_grad()
        outputs = net(data)
        loss = F.nll_loss(outputs, labels)
        loss.backward()

        optimizer.step()

【讨论】:

  • 这并没有影响任何事情
  • 即使不影响,每次迭代都必须调用zero_grad。
【解决方案2】:

我认为您应该在模型的最后一行使用log_softmax 而不是softmax。

def forward(self, X): 
    X = F.relu(self.fc1(X))
    X = F.relu(self.fc2(X))
    X = self.fc3(X)
    return F.log_softmax(X, dim=1) # => use `log_softmax` instead.

NLLLoss 要求输入为对数概率。文档说:

通过前向调用给出的输入应该包含每个类的对数概率。


此外,在 for 循环中使用 optimizer.zero_grad(),如 @Dishin's answer 中所述。

【讨论】:

  • 修复了零梯度,改为log_softmax,现在损失几乎保持不变,准确率仍然没有改变
猜你喜欢
  • 2021-09-05
  • 2019-11-24
  • 2020-05-03
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多