我有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.tile
和tf.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)
答案 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
形状
幸运的是,有一个issue和pull request
似乎可以处理有多个None
形状的情况
需要从源码(主分支)构建
我将在重新构建tensorflow之后报告结果
BTW,tf.einsum
只接受小写
报告强>
是的,最新版本的tensorflow(主分支)接受tf.einsum
的动态形状
使用tf.einsum
后,它的速度有了很大的提升,真的很棒