4

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

有类似的问题,例如计算输出相对于输入的导数,但我无法真正弄清楚发生了什么。如果这已经得到回答或微不足道,我再次道歉。非常感谢。

4

1 回答 1

1

您发布的代码应该为您提供输入的第一个输出的偏导数。但是,您还必须对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]

于 2019-12-03T22:11:54.017 回答