tensorflow batch_matmul 是如何工作的?
How does tensorflow batch_matmul work?
Tensorflow 有一个名为 batch_matmul 的函数,它可以乘以高维张量。但我很难理解它是如何工作的,部分原因可能是我很难将其形象化。
我想做的是用一个矩阵乘以一个3D张量的每个切片,但我不太明白张量a的形状是什么。 z 是最里面的维度吗?以下哪项是正确的?
我最希望第一个是正确的——它对我来说最直观并且在 .eval() 输出中很容易看到。但我怀疑第二个是正确的。
Tensorflow 表示 batch_matmul 执行:
out[..., :, :] = matrix(x[..., :, :]) * matrix(y[..., :, :])
这是什么意思?在我的例子中这意味着什么?什么乘以什么?为什么我没有按照预期的方式获得 3D 张量?
您可以将其想象为对批次中的每个训练示例执行矩阵相乘。
例如,如果您有两个具有以下维度的张量:
a.shape = [100, 2, 5]
b.shape = [100, 5, 2]
然后你做一个批处理 tf.matmul(a, b)
,你的输出将具有 [100, 2, 2]
.
的形状
100是你的batch size,另外两个维度是你数据的维度。
很简单,就是分别在第一个维度上拆分,相乘再拼接回来。如果你想通过 2D 做 3D,你可以重塑,相乘,再重塑回来。 IE。 [100, 2, 5] -> [200, 5] -> [200, 2] -> [100, 2, 2]
您现在可以使用 tf.einsum,从 Tensorflow 0.11.0rc0.
开始
例如,
M1 = tf.Variable(tf.random_normal([2,3,4]))
M2 = tf.Variable(tf.random_normal([5,4]))
N = tf.einsum('ijk,lk->ijl',M1,M2)
它将矩阵M2与M1中每批(2批)的每一帧(3帧)相乘。
输出为:
[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)]
已验证,算法正确
这个特定答案的答案是使用 tf.scan 函数。
If a = [5,3,2] #5批的尺寸,每批3X2垫
and b = [2,3] # 与每个样本相乘的常量矩阵
然后让 def fn(a,x):
return tf.matmul(x,b)
初始化器 = tf.Variable(tf.random_number(3,3))
h = tf.scan(fn、输出、初始化器)
这个 h 将存储所有输出。
首先 tf.batch_matmul()
是 removed and no longer available. Now you suppose to use tf.matmul()
:
The inputs must be matrices (or tensors of rank > 2, representing
batches of matrices), with matching inner dimensions, possibly after
transposition.
所以我们假设您有以下代码:
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
个矩阵 nxm
和 batch_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)
tf.tensordot应该可以解决这个问题。它支持批处理操作,例如,如果您想将 2D 张量与 3D 张量进行收缩,而后者具有批处理维度。
如果 a 是形状 [n,m] b 是形状 [?,m,l],那么
y = tf.tensordot(b, a, axes=[1, 1]) 将产生形状为 [?,n,l]
的张量
Tensorflow 有一个名为 batch_matmul 的函数,它可以乘以高维张量。但我很难理解它是如何工作的,部分原因可能是我很难将其形象化。
我想做的是用一个矩阵乘以一个3D张量的每个切片,但我不太明白张量a的形状是什么。 z 是最里面的维度吗?以下哪项是正确的?
我最希望第一个是正确的——它对我来说最直观并且在 .eval() 输出中很容易看到。但我怀疑第二个是正确的。
Tensorflow 表示 batch_matmul 执行:
out[..., :, :] = matrix(x[..., :, :]) * matrix(y[..., :, :])
这是什么意思?在我的例子中这意味着什么?什么乘以什么?为什么我没有按照预期的方式获得 3D 张量?
您可以将其想象为对批次中的每个训练示例执行矩阵相乘。
例如,如果您有两个具有以下维度的张量:
a.shape = [100, 2, 5]
b.shape = [100, 5, 2]
然后你做一个批处理 tf.matmul(a, b)
,你的输出将具有 [100, 2, 2]
.
100是你的batch size,另外两个维度是你数据的维度。
很简单,就是分别在第一个维度上拆分,相乘再拼接回来。如果你想通过 2D 做 3D,你可以重塑,相乘,再重塑回来。 IE。 [100, 2, 5] -> [200, 5] -> [200, 2] -> [100, 2, 2]
您现在可以使用 tf.einsum,从 Tensorflow 0.11.0rc0.
开始例如,
M1 = tf.Variable(tf.random_normal([2,3,4]))
M2 = tf.Variable(tf.random_normal([5,4]))
N = tf.einsum('ijk,lk->ijl',M1,M2)
它将矩阵M2与M1中每批(2批)的每一帧(3帧)相乘。
输出为:
[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)]
已验证,算法正确
这个特定答案的答案是使用 tf.scan 函数。
If a = [5,3,2] #5批的尺寸,每批3X2垫
and b = [2,3] # 与每个样本相乘的常量矩阵
然后让 def fn(a,x): return tf.matmul(x,b)
初始化器 = tf.Variable(tf.random_number(3,3))
h = tf.scan(fn、输出、初始化器)
这个 h 将存储所有输出。
首先 tf.batch_matmul()
是 removed and no longer available. Now you suppose to use tf.matmul()
:
The inputs must be matrices (or tensors of rank > 2, representing batches of matrices), with matching inner dimensions, possibly after transposition.
所以我们假设您有以下代码:
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
个矩阵 nxm
和 batch_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)
tf.tensordot应该可以解决这个问题。它支持批处理操作,例如,如果您想将 2D 张量与 3D 张量进行收缩,而后者具有批处理维度。
如果 a 是形状 [n,m] b 是形状 [?,m,l],那么
y = tf.tensordot(b, a, axes=[1, 1]) 将产生形状为 [?,n,l]
的张量