tensorflow - Keras/Tensorflow 批量矩阵跨轴乘法
问题描述
说我有张量
a
Out[15]: <tf.Tensor 'Placeholder_2:0' shape=(?, 1152, 8) dtype=float32>
b
Out[16]: <tf.Variable 'Variable:0' shape=(16, 8, 1152, 10) dtype=float32_ref>
a 表示一批 1152 个 8 维向量,b 是 1152*10, (16, 8) 个矩阵。
我希望将这些矩阵与 a 中的 8 维向量相乘,然后得到一个形状为 (None, 16, 1152, 10) 的张量。我知道在张量流中可以einsum
用来完成这项工作
tf.einsum('ijkl,bkj->bikl', b, a)
给我正确的输出和形状。但是与类似的功能(如or tf.einsum
)相比非常慢。但是,我很难理解这些函数如何处理轴和广播规则。有什么帮助吗?K.batch_dot
tf.tensordot
解决方案
通过使用transpose
andreshape
你可以达到同样的效果:
a : [batch, 1152, 8] --> reshape --> [batch, 1, 1, 1152, 8]
b : [16,8,1152,10] --> transpose --> [16, 10, 1152, 8]
--> expand_dims --> [1, 16, 10, 1152, 8]
multiply (a, b) --> [batch, 16, 10, 1152, 8]
reduce_sum axis 4 --> [batch, 16, 10, 1152]
代码:
#inputs
import numpy.testing as npt
x = np.random.normal(size=(5,1152,8))
y = np.random.normal(size=(16, 8, 1152, 10))
a = tf.placeholder(tf.float32,shape=(None, 1152, 8))
b = tf.constant(y, tf.float32)
out = tf.reduce_sum(tf.expand_dims(tf.transpose(b,[0, 3, 2, 1]),0)
* tf.reshape(a,[-1,1,1,tf.shape(a)[1], tf.shape(a)[2]]), axis=4)
out = tf.transpose(out, [0,1,3,2])
out_ein = tf.einsum('ijkl,bkj->bikl', b, a)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
o = sess.run(out, {a: x})
e = sess.run(out_ein, {a: x})
npt.assert_almost_equal(o, e, decimal=5)
#almost the same
推荐阅读
- r - 按变量索引时 SD[] 的性能问题
- apache-spark - pyspark udf clean html标签得到typeerror
- promise - Mithriljs m.request.then 不是函数
- c# - 如何更改 CPU ID
- javascript - 路由器链接改变了路径,但路由器视图没有改变
- javascript - 如何将 API 调用的图像结果作为背景图像附加到我的应用程序?
- c++ - 我对将值分配给 std::array 的方式有一些疑问
- python - 在 gensim 中创建一个新的向量模型
- ios - 使用 Chameleon 的结果设置 UIView.backgroundColor 时出现意外 nil
- vue.js - 如何将ui组件(物化步进器)添加到vue项目中?