对于这个问题显而易见或微不足道,我深表歉意。我是pytorch的新手,我想了解pytorch中的autograd.grad函数。我有一个神经网络G接受输入(x,t)和输出(u,v)。这是G的代码:
class GeneratorNet(torch.nn.Module):
"""
A three hidden-layer generative neural network
"""
def __init__(self):
super(GeneratorNet, self).__init__()
self.hidden0 = nn.Sequential(
nn.Linear(2, 100),
nn.LeakyReLU(0.2)
)
self.hidden1 = nn.Sequential(
nn.Linear(100, 100),
nn.LeakyReLU(0.2)
)
self.hidden2 = nn.Sequential(
nn.Linear(100, 100),
nn.LeakyReLU(0.2)
)
self.out = nn.Sequential(
nn.Linear(100, 2),
nn.Tanh()
)
def forward(self, x):
x = self.hidden0(x)
x = self.hidden1(x)
x = self.hidden2(x)
x = self.out(x)
return x
或者简单地说G(x,t)=(u(x,t),v(x,t))其中u(x,t)和v(x,t)是标量值。目标:计算$ \ frac {\ partial u(x,t)} {\ partial x} $和$ \ frac {\ partial u(x,t)} {\ partial t} $。在每个训练步骤中,我都有一个大小为$ 100 $的小批量,因此u(x,t)是一个[100,1]张量。这是我尝试计算偏导数的尝试,其中coords是输入(x,t),就像下面一样,我也将requires_grad_(True)
标志添加到了coords:
tensor = GeneratorNet(coords)
tensor.requires_grad_(True)
u, v = torch.split(tensor, 1, dim=1)
du = autograd.grad(u, coords, grad_outputs=torch.ones_like(u), create_graph=True,
retain_graph=True, only_inputs=True, allow_unused=True)[0]
du现在是[100,2]张量。 问题:这是小批量生产的100个输入点的局部张量吗?
还有类似的问题,例如针对输入计算输出的导数,但是我无法真正弄清楚发生了什么。如果已经回答或不重要,我再次表示歉意。非常感谢。
答案 0 :(得分:1)
您发布的代码应为您的第一个输出加上w.r.t.输入。但是,您还必须在输入上设置requires_grad_(True)
,因为否则PyTorch不会从输入开始构建计算图,因此无法为它们计算梯度。
此版本的代码示例将计算du
和dv
:
net = GeneratorNet()
coords = torch.randn(10, 2)
coords.requires_grad = True
tensor = net(coords)
u, v = torch.split(tensor, 1, dim=1)
du = torch.autograd.grad(u, coords, grad_outputs=torch.ones_like(u))[0]
dv = torch.autograd.grad(v, coords, grad_outputs=torch.ones_like(v))[0]
您还可以计算单个输出的偏导数:
net = GeneratorNet()
coords = torch.randn(10, 2)
coords.requires_grad = True
tensor = net(coords)
u, v = torch.split(tensor, 1, dim=1)
du_0 = torch.autograd.grad(u[0], coords)[0]
其中du_0 == du[0]
。