- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在 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/
我试图找到这 3 个函数的 Wronskian 行列式,但代码有“TypeError: No loop matching the specified signature and casting was
我需要编写一个在编译时计算行列式的 constexpr 函数。最明显的解决方案是使用拉普拉斯展开。支持 C++14。 #include #include constexpr int get_cof
是否有任何类似 A * A-1 = I 的数学性质可用于测试类似格式的单元测试中行列式的计算? 最佳答案 手动计算一个(或多个)已知数组的行列式,并将您的结果与该数字进行比较。 尝试不同大小、排列方式
我有一个大的 numpy 数组 arr,形状为 (N, D, M, D) 其中 D 是两个或三。该数组可以被认为是 (D,D) 矩阵 block ,这些矩阵在 N 和 M 维度中被阻塞在一起。我想取这
我是一名优秀的程序员,十分优秀!