Matmul有不同的级别

时间:2017-03-08 13:55:24

标签: python tensorflow vectorization

我有3个张量 X(1, c, h, w),假设(1, 20, 40, 50)
Fx(num, w, N),假设(1000, 50, 10)
Fy(num, N, h),假设为(1000, 10, 40)

我想要做的是Fy * (X * Fx)*表示matmul
X * Fx(num, c, h, N),假设(1000, 20, 40, 10)
Fy * (X * Fx)(num, c, N, N),假设为(1000, 20, 10, 10)

我正在使用tf.tiletf.expand_dims来执行此操作 但我认为它使用了大量内存(tile复制数据对吗?),并且慢了 尝试找到更好的方法,更快,并使用小内存来完成

# 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)

2 个答案:

答案 0 :(得分:2)

mythical einsum的情况,我想:

>>> 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版本中,使用大写索引是不允许的,我看到了)。虽然如果你之前从未见过这种表示法,这无可否认地超过了正则表达式。

答案 1 :(得分:0)

对于其他可能感兴趣的人 我认为@phg的答案可能有效 但就我而言,num h w是动态的,即None
因此,张量流r1.0中的tf.einsum会引发错误,因为一个张量中有多个None形状

幸运的是,有一个issuepull request
似乎可以处理有多个None形状的情况 需要从源码(主分支)构建
我将在重新构建tensorflow之后报告结果

BTW,tf.einsum只接受小写

报告
是的,最新版本的tensorflow(主分支)接受tf.einsum的动态形状 使用tf.einsum后,它的速度有了很大的提升,真的很棒