【问题标题】:Getting gradient of vectorized function in pytorch在pytorch中获取矢量化函数的梯度
【发布时间】:2019-04-18 15:24:44
【问题描述】:

我是 PyTorch 的新手,想做一件我认为很简单但遇到很多困难的事情。

我有函数sin(x) * cos(x) + x^2,我想在任何时候得到该函数的导数。

如果我做到这一点,它可以完美地发挥作用

x = torch.autograd.Variable(torch.Tensor([4]),requires_grad=True)
y = torch.sin(x)*torch.cos(x)+torch.pow(x,2)
y.backward()
print(x.grad) # outputs tensor([7.8545])

但是,我希望能够将向量作为 x 传递,并让它按元素计算导数。例如:

Input: [4., 4., 4.,]
Output: tensor([7.8545, 7.8545, 7.8545])

但我似乎无法让它工作。

我试着简单地做

x = torch.tensor([4., 4., 4., 4.], requires_grad=True)
out = torch.sin(x)*torch.cos(x)+x.pow(2)
out.backward()
print(x.grad)

但我收到错误“RuntimeError: grad can be implicitly created only for scalar outputs”

如何为向量调整此代码?

提前致谢,

【问题讨论】:

    标签: python pytorch derivative autodiff


    【解决方案1】:

    Here你可以找到关于你的错误的相关讨论。

    本质上,当您调用不带参数的backward() 时,它会隐式转换为backward(torch.Tensor([1])),其中torch.Tensor([1]) 是计算梯度的输出值。

    如果您传递4(或更多)输入,则每个输入都需要一个用于计算梯度的值。您可以像这样将torch.ones_like 显式传递给backward

    import torch
    
    x = torch.tensor([4.0, 2.0, 1.5, 0.5], requires_grad=True)
    out = torch.sin(x) * torch.cos(x) + x.pow(2)
    # Pass tensor of ones, each for each item in x
    out.backward(torch.ones_like(x))
    print(x.grad)
    

    【讨论】:

    • 太棒了。非常感谢!
    猜你喜欢
    • 2018-05-16
    • 2020-04-04
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2019-11-12
    • 1970-01-01
    • 2019-01-05
    相关资源
    最近更新 更多