Python 不同等级的马特穆尔
我有3个张量Python 不同等级的马特穆尔,python,tensorflow,vectorization,Python,Tensorflow,Vectorization,我有3个张量 X形状(1,c,h,w),假设(1,20,40,50) Fxshape(num,w,N),假设(1000,50,10) Fyshape(num,N,h),假设(1000,10,40) 我想做的是Fy*(X*Fx)(*表示matmul) X*Fxshape(num,c,h,N),假设(1000,20,40,10) Fy*(X*Fx)shape(num,c,N,N),假设(1000,20,10,10) 我正在使用tf.tile和tf.expand_dims来执行此操作 但是我认为它使用
X
形状(1,c,h,w)
,假设(1,20,40,50)
Fx
shape(num,w,N)
,假设(1000,50,10)
Fy
shape(num,N,h)
,假设(1000,10,40)
我想做的是Fy*(X*Fx)
(*
表示matmul
)X*Fx
shape(num,c,h,N)
,假设(1000,20,40,10)
Fy*(X*Fx)
shape(num,c,N,N)
,假设(1000,20,10,10)
我正在使用tf.tile
和tf.expand_dims
来执行此操作但是我认为它使用了大量内存(
tile
copydataright?),而且速度很慢试着找到更快更好的方法,并使用较小的内存来完成
# X: (1, c, h, w)
# Fx: (num, w, N)
# Fy: (num, N, h)
X = tf.tile(X, [tf.shape(Fx)[0], 1, 1, 1]) # (num, c, h, w)
Fx_ex = tf.expand_dims(Fx, axis=1) # (num, 1, w, N)
Fx_ex = tf.tile(Fx_ex, [1, c, 1, 1]) # (num, c, w, N)
tmp = tf.matmul(X, Fxt_ex) # (num, c, h, N)
Fy_ex = tf.expand_dims(Fy, axis=1) # (num, 1, N, h)
Fy_ex = tf.tile(Fy_ex, [1, c, 1, 1]) # (num, c, N, h)
res = tf.matmul(Fy_ex, tmp) # (num, c, N, N)
我想这是一个例子:
>>> import numpy as np
>>> X = np.random.rand(1, 20, 40, 50)
>>> Fx = np.random.rand(100, 50, 10)
>>> Fy = np.random.rand(100, 10, 40)
>>> np.einsum('nMh,uchw,nwN->ncMN', Fy, X, Fx).shape
(100, 20, 10, 10)
它在
tf
中的工作原理应该与numpy
中的工作原理几乎相同(我看到,在一些tf
版本中不允许使用大写索引)。尽管如果您以前从未见过这种符号,那么这在不可读性方面无疑超过了正则表达式。对于其他人,您可能会感兴趣我认为@phg的答案可能有用
但是在我的例子中,
num
h
w
是动态的,即None
因此,tensorflow r1.0中的
tf.einsum
将产生错误,因为一个张量中有多个None
形状
幸运的是,有一个和似乎可以处理多个
None
shape需要从源代码构建(主分支)
我将在重建tensorflow后报告结果 顺便说一句,在
tf.einsum
中只接受小写
报告是的,tensorflow(主分支)的最新版本接受
tf.einsum的动态形状
使用tf.einsum
后速度有了巨大的提高,真是太棒了是的,我以前从未见过这个,有点难以理解,试图理解这个想法