gpt4 book ai didi

python - Pytorch中神经网络的前向雅可比行列式很慢

转载 作者:太空宇宙 更新时间:2023-11-03 21:19:50 25 4
gpt4 key购买 nike

我正在 pytorch 中计算 2 层前馈神经网络的前向雅可比(输出相对于输入的导数),我的结果是正确的,但相对较慢。考虑到计算的性质,我预计它的速度大约与通过网络的前向传递一样快(或者可能是 2-3 倍长),但在此例程上运行优化步骤需要大约 12 倍的时间(在我的例子中)测试示例我只想要 jacobian=1 在所有点)与标准均方误差,所以我假设我正在以非最佳方式做某事。我只是想知道是否有人知道更快的编码方法。我的测试网络有 2 个输入节点,后面是 2 个隐藏层,每个隐藏层有 5 个节点,还有一个输出层有 2 个节点,并在隐藏层上使用 tanh 激活函数,并具有线性输出层。

雅可比行列式计算基于论文The Limitations of Deep Learning in Adversarial Settings它给出了前向导数的基本递归定义(基本上,您最终将激活函数的导数与每层的权重和先前的偏导数相乘)。这与前向传播非常相似,这就是为什么我期望它比实际速度更快。那么最后 2x2 雅可比行列式就非常简单了。

下面是网络和雅可比的代码

class Network(torch.nn.Module):
def __init__(self):
super(Network, self).__init__()
self.h_1_1 = torch.nn.Linear(input_1, hidden_1)
self.h_1_2 = torch.nn.Linear(hidden_1, hidden_2)
self.out = torch.nn.Linear(hidden_2, out_1)


def forward(self, x):
x = F.tanh(self.h_1_1(x))
x = F.tanh(self.h_1_2(x))
x = (self.out(x))
return x

def jacobian(self, x):
a = self.h_1_1.weight
x = F.tanh(self.h_1_1(x))
tanh_deriv_tensor = 1 - (x ** 2)
expanded_deriv = tanh_deriv_tensor.unsqueeze(-1).expand(-1, -1, input_1)
partials = expanded_deriv * a.expand_as(expanded_deriv)

a = torch.matmul(self.h_1_2.weight, partials)
x = F.tanh(self.h_1_2(x))
tanh_deriv_tensor = 1 - (x ** 2)
expanded_deriv = tanh_deriv_tensor.unsqueeze(-1).expand(-1, -1, out_1)
partials = expanded_deriv*a

partials = torch.matmul(self.out.weight, partials)

determinant = partials[:, 0, 0] * partials[:, 1, 1] - partials[:, 0, 1] * partials[:, 1, 0]
return determinant

这是正在比较的两个误差函数。请注意,第一个函数需要通过网络进行额外的前向调用,以获取输出值(标记为操作),而第二个函数则不需要,因为它作用于输入值。

def actor_loss_fcn1(action, target):
loss = ((action-target)**2).mean()
return loss

def actor_loss_fcn2(input): # 12x slower
jacob = model.jacobian(input)
loss = ((jacob-1)**2).mean()
return loss

对此的任何见解将不胜感激

最佳答案

第二次计算“a”在我的机器(CPU)上花费的时间最多。

# Here you increase the size of the matrix with a factor of "input_1"
expanded_deriv = tanh_deriv_tensor.unsqueeze(-1).expand(-1, -1, input_1)
partials = expanded_deriv * a.expand_as(expanded_deriv)

# Here your torch.matmul() needs to handle "input_1" times more computations than in a normal forward call
a = torch.matmul(self.h_1_2.weight, partials)

在我的机器上,计算雅可比行列式的时间大致等于 torch 计算所需的时间

a = torch.rand(hidden_1, hidden_2)
b = torch.rand(n_inputs, hidden_1, input_1)
%timeit torch.matmul(a,b)

我认为从计算角度来说不可能加快速度。除非你可以从 CPU 迁移到 GPU,因为 GPU 在大型矩阵上会变得更好。

关于python - Pytorch中神经网络的前向雅可比行列式很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54383474/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com