Getting gradient of vectorized function in pytorch

久未见 提交于 2021-02-20 00:46:41

问题


I am brand new to PyTorch and want to do what I assume is a very simple thing but am having a lot of difficulty.

I have the function sin(x) * cos(x) + x^2 and I want to get the derivative of that function at any point.

If I do this with one point it works perfectly as

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])

However, I want to be able to pass in a vector as x and for it to evaluate the derivative element-wise. For example:

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

But I can't seem to get this working.

I tried simply doing

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)

But I get the error "RuntimeError: grad can be implicitly created only for scalar outputs"

How do I adjust this code for vectors?

Thanks in advance,


回答1:


Here you can find relevant discussion about your error.

In essence, when you call backward() without arguments it is implicitly converted to backward(torch.Tensor([1])), where torch.Tensor([1]) is the output value with respect to which gradients are calculated.

If you pass 4 (or more) inputs, each needs a value with respect to which you calculate gradient. You can pass torch.ones_like explicitly to backward like this:

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)


来源:https://stackoverflow.com/questions/55749202/getting-gradient-of-vectorized-function-in-pytorch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!