tensorflow batch_matmul如何工作?

时间:2015-12-09 16:00:08

标签: numpy scipy tensorflow

Tensorflow有一个名为batch_matmul的函数,它可以乘以更高维的张量。但是我很难理解它是如何工作的,也许部分是因为我很难想象它。

enter image description here

我想要做的是将矩阵乘以3D张量的每个切片,但我不太明白张量a的形状是什么。 z是最里面的维度吗?以下哪项是正确的?

enter image description here

我最希望第一个是正确的 - 它对我来说最直观,在.eval()输出中很容易看到。但我怀疑第二个是正确的。

Tensorflow说batch_matmul执行:

out[..., :, :] = matrix(x[..., :, :]) * matrix(y[..., :, :])

这是什么意思?在我的例子中,这意味着什么?什么与什么相乘?为什么我没有按照预期的方式获得3D张量?

6 个答案:

答案 0 :(得分:21)

您可以将其想象为对批处理中的每个培训示例进行管理。

例如,如果您有两个具有以下尺寸的张量:

a.shape = [100, 2, 5]
b.shape = [100, 5, 2]

并且您执行批处理tf.matmul(a, b),您的输出将具有[100, 2, 2]形状。

100是您的批量大小,其他两个维度是数据的维度。

答案 1 :(得分:14)

首先tf.batch_matmul()removed,不再可用。现在你想使用tf.matmul()

  

输入必须是矩阵(或等级> 2的张量,代表   批次的矩阵,具有匹配的内部尺寸,可能在之后   转置。

因此,我们假设您有以下代码:

import tensorflow as tf
batch_size, n, m, k = 10, 3, 5, 2
A = tf.Variable(tf.random_normal(shape=(batch_size, n, m)))
B = tf.Variable(tf.random_normal(shape=(batch_size, m, k)))
tf.matmul(A, B)

现在您将收到形状(batch_size, n, k)的张量。这是这里发生的事情。假设您有batch_size个矩阵nxmbatch_size矩阵mxk。现在,对于每对它们,您计算nxm X mxk,它会为您提供nxk矩阵。你将拥有batch_size个。

请注意,这样的内容也是有效的:

A = tf.Variable(tf.random_normal(shape=(a, b, n, m)))
B = tf.Variable(tf.random_normal(shape=(a, b, m, k)))
tf.matmul(A, B)

并为您提供(a, b, n, k)

形状

答案 2 :(得分:4)

现在可以使用tf.einsum,从Tensorflow 0.11.0rc0 开始。

例如,

[array([[[ 0.80474716, -1.38590837, -0.3379252 , -1.24965811],
        [ 2.57852983,  0.05492432,  0.23039417, -0.74263287],
        [-2.42627382,  1.70774114,  1.19503212,  0.43006262]],

       [[-1.04652011, -0.32753903, -1.26430523,  0.8810069 ],
        [-0.48935518,  0.12831448, -1.30816901, -0.01271309],
        [ 2.33260512, -1.22395933, -0.92082584,  0.48991606]]], dtype=float32),
array([[ 1.71076882, 0.79229093, -0.58058828, -0.23246667],
       [ 0.20446332,  1.30742455, -0.07969904,  0.9247328 ],
       [-0.32047141,  0.66072595, -1.12330854,  0.80426538],
       [-0.02781649, -0.29672042,  2.17819595, -0.73862702],
       [-0.99663496,  1.3840003 , -1.39621222,  0.77119476]], dtype=float32), 
array([[[ 0.76539308, 2.77609682, -1.79906654,  0.57580602, -3.21205115],
        [ 4.49365759, -0.10607499, -1.64613271,  0.96234947, -3.38823152],
        [-3.59156275,  2.03910899,  0.90939498,  1.84612727,  3.44476724]],

       [[-1.52062428,  0.27325237,  2.24773455, -3.27834225,  3.03435063],
        [ 0.02695178,  0.16020992,  1.70085776, -2.8645196 ,  2.48197317],
        [ 3.44154787, -0.59687197, -0.12784094, -2.06931567, -2.35522676]]], dtype=float32)]

它将矩阵M2乘以M1中每批(2批)的每帧(3帧)。

输出结果为:

#!/bin/bash

string='"thumbnailUrl": "http://placehold.it/150/adf4e1"'
string="${string//\"}"
echo "${string##*/}"

adf4e1 #output

我已经验证,算术是正确的。

答案 3 :(得分:2)

tf.tensordot应该可以解决此问题。它支持批处理操作,例如,如果您想用3D张量收缩2D张量,而后者具有批处理尺寸。

如果a为[n,m]形状,b为[?,m,l]形状,则

y = tf.tensordot(b,a,axes = [1,1])将产生形状为[?,n,l]的张量

https://www.tensorflow.org/api_docs/python/tf/tensordot

答案 4 :(得分:-1)

它就像分别在第一维上分裂一样,将它们相乘并连接起来。如果你想通过2D做3D,你可以重新塑造,复制和重塑它。即[100,2,5] - > [200,5] - > [200,2] - > [100,2,2]

答案 5 :(得分:-1)

这个特定答案的答案是使用tf.scan函数。

如果a = [5,3,2] #dimension of 5 batch,每批中有3X2垫 和b = [2,3]#一个与每个样本相乘的常数矩阵

然后让def fn(a,x):               return tf.matmul(x,b)

initializer = tf.Variable(tf.random_number(3,3))

h = tf.scan(fn,outputs,initializer)

这个h将存储所有输出。