Python 不同等级的马特穆尔

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来执行此操作 但是我认为它使用

我有3个张量
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
后速度有了巨大的提高,真是太棒了

是的,我以前从未见过这个,有点难以理解,试图理解这个想法