如何使用PyTorch计算输出功率的梯度神经网络中的输入?

时间:2018-08-03 06:21:15

标签: neural-network gradient pytorch

我的网络训练有素。我想计算输出功率的斜率输入。通过查询PyTorch文档, torch.autograd.grad 可能会有用。 因此,我使用以下代码:

    x_test = torch.randn(D_in,requires_grad=True)
    y_test = model(x_test)
    d = torch.autograd.grad(y_test, x_test)[0]

model是神经网络。 x_test是大小为D_in的输入,而y_test是标量输出。 我想将计算结果与scipy.misc.derivative的数值差进行比较。 因此,我通过设置索引来计算偏导数。

    idx = 3
    x_test = torch.randn(D_in,requires_grad=True)
    y_test = model(x_test)
    print(x_test[idx].item())
    d = torch.autograd.grad(y_test, x_test)[0]
    print(d[idx].item())
    def fun(x):
        x_input = x_test.detach()
        x_input[idx] = x
        with torch.no_grad():
            y = model(x_input)
        return y.item()
    x0 = x_test[idx].item()
    print(x0)
    print(derivative(fun, x0, dx=1e-6))

但是我得到了完全不同的结果。 torch.autograd.grad计算出的梯度为-0.009522666223347187, 而scipy.misc.derivative的数字是-0.014901161193847656

计算是否有问题?还是我误用了torch.autograd.grad

1 个答案:

答案 0 :(得分:0)

实际上,您给定的代码很可能是完全正确的。 让我通过将您重定向到有关反向传播的一些背景信息(或在本例中为自动差分(AutoDiff))来说明这一点。

许多软件包的特定实现基于AutoGrad,AutoGrad是获取函数/图形的 exact 派生类的常用技术。它可以通过实质上“反转”正向计算过程来计算原子功能块的分段导数(例如加法,减法,乘法,除法等),然后“将它们链接在一起”来完成此操作。
我在this question的更详细的答案中解释了AutoDiff及其详细信息。

相反,通过使用有限差分,scipy的导数函数只是对该导数的逼近。您将在附近的点获取函数的结果,然后基于这些点的函数值之差来计算导数。这就是为什么您会看到两个梯度略有不同的原因,因为这可能是对实际导数的不准确表示。