在我的一个神经网络实现中,我必须解决以下问题:
w = f(v)
其中Lv = q+Dw
, w
,是向量,v
是矩阵并且是对角矩阵。这当然看起来像是一个困难的依赖问题,但如果我们假设严格来说是下三角,那么这个问题是可以迭代解决的。为了清楚起见,我将在下面写出问题:q
D
L
D
[l1 0 0 ... 0 ] [v1] [ 0 0 0 ... 0] [w1] [q1]
[ 0 l2 0 ... : ] [v2] [D21 0 0 ... :] [w2] [q2]
[ 0 0 l3 ... : ] [v3] = [D31 D32 0 ... :] [w3] + [q3]
[ : : : ... 0 ] [ :] [ : : : :] [ :] [ :]
[ 0 0 0 ... ln] [vn] [Dn1 Dn2 ...Dnn-1 0] [wn] [qn]
[w1] ( [v1] )
[ :] = f( [ :] )
[wn] ( [vn] )
(我希望由于缺乏数学排版很清楚:P)
我在批量设置中解决了这个问题,因此向量w
, v
,q
的维度为(N_batch, n)
。
由于我不是 python 专家,我现在只看到使用以下迭代过程解决此问题的可能性:
l = torch.diag(L) # size: (n,)
vi = [ (1 / l[0]) * q[:, 0] ] # size: (N_batch, 1)
for i in range(1, n):
# building up the vector w out of v1 ... vi
w = f(torch.stack(vi, dim=1))
# calculate the new vi with the new w vector
vi.append( (1 / l[0]) * ( q[:,i] + torch.einsum('j,bj->b', D[i,:i], w) ) )
# final step
w1_n = f( torch.stack(vi, dim=1) )
然而,这实际上占用了 85% 的时间来计算我在神经网络训练中的一步前进过程,因此优化这个过程会非常好:P
是否有一些我不知道的功能可以解决这个问题,或者是否有一些 python 大师可以优化我的问题?先谢谢了
MWE:
import torch
import time
n = 20
N_batch = 150
l = torch.rand(n)+1 # size: (n,)
q = torch.rand(N_batch, n)
f = torch.nn.Tanh()
D = torch.tril(torch.rand(n,n),diagonal=-1)
tic = time.time()
vi = [ (1 / l[0]) * q[:, 0] ] # size: (N_batch, 1)
for i in range(1, n):
# building up the vector w out of v1 ... vi
w = f(torch.stack(vi, dim=1))
# calculate the new vi with the new w vector
vi.append( (1 / l[0]) * ( q[:,i] + torch.einsum('j,bj->b', D[i,:i], w) ) )
# final step
w1_n = f( torch.stack(vi, dim=1) )
print('Total time: ' + str(time.time()-tic))