使用autograd计算相对于输入的输出雅可比矩阵

时间:2019-12-03 16:03:24

标签: pytorch autograd

对于这个问题显而易见或微不足道,我深表歉意。我是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个输入点的局部张量吗?

还有类似的问题,例如针对输入计算输出的导数,但是我无法真正弄清楚发生了什么。如果已经回答或不重要,我再次表示歉意。非常感谢。

1 个答案:

答案 0 :(得分:1)

您发布的代码应为您的第一个输出加上w.r.t.输入。但是,您还必须在输入上设置requires_grad_(True),因为否则PyTorch不会从输入开始构建计算图,因此无法为它们计算梯度。

此版本的代码示例将计算dudv

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]

相关问题