如何在pytorch中计算此高维矩阵的梯度?

时间:2018-09-18 17:18:05

标签: python pytorch torch

我从pytorch文档中得到了一个简单的示例,其中使用autograd通过this example进行梯度下降。这是我简单的工作示例:

s = np.linspace(-1,1,100)
#The "data"
x = torch.tensor(np.stack((s**2,s**3,s),axis=1), device=device, dtype=dtype)
v_coeffs = np.array([5,-2,4])
#The "target"
v = torch.tensor(np.expand_dims(v_coeffs[0]*s + v_coeffs[1]*s**2 + v_coeffs[2]*s**3,axis=1), device=device, dtype=dtype)
#The weights to determine
w = torch.randn(3, 1, device=device, dtype=dtype, requires_grad=True)
alpha = 10**-4

for t in range(t_range):
    vhat = x.mm(w)
    J = (v - vhat).pow(2).sum()
    J.backward()

    with torch.no_grad():

        w -= alpha*w.grad
        w.grad.zero_()

它有效。如果我绘制w的值,我会发现它们接近“目标” v的系数:

convergence of weights picture

例如,x.shape =(100,3),v.shape =(100,1),w.shape =(3,1)。所以x.mm(w).shape =(100,1)。

现在我正在尝试做相同的事情,但是我的权重矩阵具有更大的尺寸:其形状为W.shape =(40,40,2)。我的X将是一批(40,40,2)矩阵,因此它的X.shape =(N,40,40,2)。

就像上面的简单示例一样,我想通过乘以X * W得到形状(N,1)的张量。我无法弄清楚如何使用内置的割炬功能来执行此操作。我已经尝试过mm(),mul(),matmul()和bmm(),但它们似乎都无法满足我的要求。除了mul()以外,大多数这些抛出的错误都与大小有关,但它们返回的大小张量与X相同。

我尝试通过列表理解并逐个元素地以这种hack-y方式进行操作:

Q = torch.Tensor([torch.sum(x*W) for x in X])

但是当我使用Q计算J.backward()时,它将引发错误:

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

我不知道这是什么意思,但是我怀疑这是因为我做了list comp,而现在Q并不“知道” W,并且require_grad()为true。在简单的工作示例中,vhat是直接从w计算出来的,因此似乎J“知道” w需要grad。

我该怎么做?

编辑:我发现我可以做到这一点:

Q = torch.sum(X.mul(W),dim=[1,2,3])

但它似乎仍然是一种解决方法...

0 个答案:

没有答案