optimizer.step() 如何取模型最近的损失?

how does optimizer.step() takes the recent loss of the model?

我正在看一个模型的pytorch的例子:

https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py

for epoch in range(2): # 多次遍历数据集

running_loss = 0.0
for i, data in enumerate(trainloader, 0):
    # get the inputs; data is a list of [inputs, labels]
    inputs, labels = data

    # zero the parameter gradients
    optimizer.zero_grad()

    # forward + backward + optimize
    outputs = net(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

    # print statistics
    running_loss += loss.item()
    if i % 2000 == 1999:    # print every 2000 mini-batches
        print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}')
        running_loss = 0.0

print('Finished Training')

我有一个非常基本的问题 - 优化器从未插入或定义到模型中(类似于 keras 中的 model.compile)。它也没有收到最后一批或时代的损失或标签。 它如何“知道”执行优化步骤?

在优化器实例化时传递模型参数:

optimizer = optim.Adam(model.parameters())

optimizer.step 更新这些参数。

在调用 step 方法之前在 loss.backward() 步计算梯度。

与其考虑损失和参数之间的关系,不如将它们视为没有关联的独立事件。实际上,有两个不同的元素会影响参数及其缓存的梯度。

  • autograd 机制(负责执行梯度计算的进程)允许您在 torch.Tensor(你的损失),这将依次反向传播所有允许计算此最终张量值的节点张量。这样做,它将浏览所谓的计算图,通过更改它们的 grad 属性来更新每个参数的梯度。这意味着在 backward 调用结束时,用于计算此输出的网络学习参数将具有 grad 属性,其中包含关于该参数的损失梯度。

    loss.backward()
    
  • 优化器 独立于反向传递,因为它不依赖它。根据您的用例,您可以一次、多次或以不同的损失条款向后调用您的图表。优化器的任务是独立获取模型参数(与网络架构或其计算图无关)并使用给定的优化例程(例如通过 Stochastic Gradient Descent, Root Mean Squared Propagation 等)更新它们。它遍历初始化时使用的所有参数,并使用它们各自的梯度值更新它们(应该通过至少一次反向传播将其存储在 grad 属性中。

    optimizer.step()
    

重要提示:

  • 请记住,虽然后向过程和使用优化器的实际更新调用是隐式链接的,但优化器将使用前向后调用计算的结果。

  • 在 PyTorch 中,参数梯度保存在内存中,因此您必须在执行新的反向调用之前清除它们。这是使用优化器的 zero_grad 函数完成的。实际上,它会清除已注册为参数的张量的 grad 属性。