权值被分割时,权重更新是如何在动态计算图的割炬代码中工作的(=多次重用)
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权重发生了什么变化。
发布于 2019-01-18 09:53:10
当您调用backward (作为函数或张量上的方法)时,使用requires_grad == True的操作数的梯度是相对于您称为backward on的张量计算的。这些梯度是在这些操作数的.grad属性中积累的。如果同一个操作数A在表达式中多次出现,您可以在概念上将它们作为单独的实体-- A1、A2.对反向传播算法和它们的梯度进行求和,使A.grad = A1.grad + A2.grad + ...。
严格地说,你的问题的答案
我想知道每一次向后的middle_linear重量会发生什么变化。
是:没什么。backward不改变权重,只计算梯度。要更改权重,您必须执行一个优化步骤,也许可以使用torch.optim中的优化器之一。然后根据其.grad属性更新权重,因此如果您的操作数被多次使用,则将相应地将其更新为每次使用中的梯度之和。
换句话说,如果您的矩阵元素x在第一次应用时具有正梯度,而在第二次使用时为负值,则可能是净效果将抵消,它将保持原样(或只改变一点点)。如果这两个应用程序都要求x更高,那么它将比仅使用一次的情况更多,等等。
https://stackoverflow.com/questions/54250651
复制相似问题