【问题标题】:How to use PyTorch to calculate the gradients of outputs w.r.t. the inputs in a neural network?如何使用 PyTorch 计算输出 w.r.t 的梯度。神经网络中的输入?
【发布时间】:2019-01-10 23:31:39
【问题描述】:

我有一个训练有素的网络。我想计算输出w.r.t的梯度。 输入。通过查询 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

【问题讨论】:

  • 我正在实现集成梯度,并计算输出 w.r.t 的相同事物梯度。输入。您能否向我解释一下您的情况下输入和输出都有什么类型?

标签: neural-network gradient pytorch


【解决方案1】:

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

许多包的具体实现基于 AutoGrad,这是一种获得函数/图的精确导数的常用技术。它可以通过基本上“反转”前向计算传递来计算原子功能块的分段导数,如加法、减法、乘法、除法等,然后将它们“链接在一起”来实现这一点。
我在this question 的更详细答案中解释了 AutoDiff 及其细节。

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

【讨论】:

    猜你喜欢
    • 2017-04-26
    • 2019-09-24
    • 2022-01-13
    • 2021-04-01
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 2021-07-23
    相关资源
    最近更新 更多