pytorch动态计算图中的权重更新如何工作?

时间:2019-01-18 09:06:17

标签: deep-learning pytorch computation-graph

权重分片(=重复使用多次)时,权重更新如何在动态计算图的Pytorch代码中起作用

https://pytorch.org/tutorials/beginner/examples_nn/dynamic_net.html#sphx-glr-beginner-examples-nn-dynamic-net-py

import random
import torch

class DynamicNet(torch.nn.Module):
    def __init__(self, D_in, H, D_out):
    """
    In the constructor we construct three nn.Linear instances that we will use
    in the forward pass.
    """
    super(DynamicNet, self).__init__()
    self.input_linear = torch.nn.Linear(D_in, H)
    self.middle_linear = torch.nn.Linear(H, H)
    self.output_linear = torch.nn.Linear(H, D_out)

def forward(self, x):
    """
    For the forward pass of the model, we randomly choose either 0, 1, 2, or 3
    and reuse the middle_linear Module that many times to compute hidden layer
    representations.

    Since each forward pass builds a dynamic computation graph, we can use normal
    Python control-flow operators like loops or conditional statements when
    defining the forward pass of the model.

    Here we also see that it is perfectly safe to reuse the same Module many
    times when defining a computational graph. This is a big improvement from Lua
    Torch, where each Module could be used only once.
    """
    h_relu = self.input_linear(x).clamp(min=0)
    for _ in range(random.randint(0, 3)):
        h_relu = self.middle_linear(h_relu).clamp(min=0)
    y_pred = self.output_linear(h_relu)
    return y_pred

我想知道每次向后middle_linear的重量会发生什么,而每次重复使用多次

1 个答案:

答案 0 :(得分:1)

当您调用backward(作为张量的函数或方法)时,相对于您调用requires_grad == True的张量计算带有backward的操作数的梯度。这些梯度是在这些操作数的.grad属性中累积的。如果同一操作数A在表达式中多次出现,则可以从概念上将它们视为单独的实体A1A2 ...以进行反向传播算法,最后将它们的梯度求和这样A.grad = A1.grad + A2.grad + ...

现在,严格来说,这是您问题的答案

  

我想知道在每次向后的中间线性 weight 发生了什么

是:什么都没有。 backward不会改变权重,只会计算梯度。要更改权重,您必须执行优化步骤,也许使用torch.optim中的优化器之一。然后根据权重的.grad属性更新权重,因此,如果多次使用您的操作数,则将根据每次使用中的梯度总和进行相应的更新。

换句话说,如果您的矩阵元素x首次应用时具有正梯度,而第二次使用时具有负梯度,则可能是净效果会抵消并且保持原样(或改变)一点点)。如果两个应用程序都要求x更高,它将比仅使用一次,等等提高更多。