通过计算雅可比行列式有效地使用PyTorch的autograd与张量

在我之前的问题中,我发现了如何将 PyTorch 的 autograd 与张量一起使用:

import torch
from torch.autograd import grad
import torch.nn as nn
import torch.optim as optim

class net_x(nn.Module): 
        def __init__(self):
            super(net_x, self).__init__()
            self.fc1=nn.Linear(1, 20) 
            self.fc2=nn.Linear(20, 20)
            self.out=nn.Linear(20, 4) #a,b,c,d

        def forward(self, x):
            x=torch.tanh(self.fc1(x))
            x=torch.tanh(self.fc2(x))
            x=self.out(x)
            return x

nx = net_x()

#input
t = torch.tensor([1.0, 2.0, 3.2], requires_grad = True) #input vector
t = torch.reshape(t, (3,1)) #reshape for batch

#method 
dx = torch.autograd.functional.jacobian(lambda t_: nx(t_), t)
dx = torch.diagonal(torch.diagonal(dx, 0, -1), 0)[0] #first vector
#dx = torch.diagonal(torch.diagonal(dx, 1, -1), 0)[0] #2nd vector
#dx = torch.diagonal(torch.diagonal(dx, 2, -1), 0)[0] #3rd vector
#dx = torch.diagonal(torch.diagonal(dx, 3, -1), 0)[0] #4th vector
dx 
>>> 
tensor([-0.0142, -0.0517, -0.0634])

问题是 grad只知道如何从标量张量传播梯度(我的网络输出不是),这就是我必须计算雅可比行列式的原因。

但是,这不是很有效并且有点慢,因为我的矩阵很大并且计算整个雅可比矩阵需要一段时间(而且我也没有使用整个雅可比矩阵)。

有没有办法只计算雅可比矩阵的对角线(在这个例子中得到 4 个向量)?

似乎有一个开放的功能请求但似乎没有得到太多关注。

更新 1:
我尝试了@iacob 所说的设置torch.autograd.functional.jacobian(vectorize=True)
然而,这似乎更慢。为了测试这一点,我将网络输出从 更改4400,并将输入t更改为:

val = 100
t = torch.rand(val, requires_grad = True) #input vector
t = torch.reshape(t, (val,1)) #reshape for batch

没有vectorized = True

Wall time: 10.4 s

和:

Wall time: 14.6 s

以上是通过计算雅可比行列式有效地使用PyTorch的autograd与张量的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>