TensorFlow 中 tf.matmul 没有广播
No broadcasting for tf.matmul in TensorFlow
我遇到了一个一直困扰我的问题。跟tf.matmul()
和没有广播有关
我知道 https://github.com/tensorflow/tensorflow/issues/216 上有一个类似的问题,但 tf.batch_matmul()
看起来不像我的情况的解决方案。
我需要将输入数据编码为 4D 张量:
X = tf.placeholder(tf.float32, shape=(None, None, None, 100))
第一个维度是批次的大小,第二个维度是批次中的条目数。
您可以将每个条目想象成多个对象的组合(三维)。最后,每个对象都由一个包含 100 个浮点值的向量来描述。
请注意,我对第二个和第三个维度使用了 None,因为每个批次的实际尺寸可能会发生变化。但是,为简单起见,让我们用实际数字塑造张量:
X = tf.placeholder(tf.float32, shape=(5, 10, 4, 100))
这些是我的计算步骤:
计算每个包含 100 个浮点值的向量的函数(例如,线性函数)
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1))
Y = tf.matmul(X, W)
问题:tf.matmul()
没有广播,使用 tf.batch_matmul()
也没有成功
Y 的预期形状:(5, 10, 4, 50)
为批次的每个条目应用平均池化(在每个条目的对象上):
Y_avg = tf.reduce_mean(Y, 2)
Y_avg 的预期形状:(5, 10, 50)
我预计 tf.matmul()
会支持广播。然后我发现 tf.batch_matmul()
,但它看起来仍然不适用于我的情况(例如,W 至少需要有 3 个维度,不清楚为什么)。
顺便说一句,上面我使用了一个简单的线性函数(其权重存储在W中)。但在我的模型中,我有一个深层网络。所以,我遇到的更普遍的问题是自动为张量的每个切片计算一个函数。这就是为什么我预计 tf.matmul()
会有广播行为(如果是这样,也许甚至不需要 tf.batch_matmul()
)。
期待向您学习!
阿莱西奥
您可以通过将 X
重塑为 [n, d]
来实现这一点,其中 d
是单个 "instance" 计算的维数(在您的示例中为 100),并且n
是多维对象中这些实例的数量(在您的示例中为 5*10*4=200
)。重塑后,您可以使用 tf.matmul
然后重塑回所需的形状。前三个维度可以变化的事实使这有点棘手,但您可以使用 tf.shape
来确定 运行 时间内的实际形状。最后,您可以执行计算的第二步,这应该是对相应维度的简单 tf.reduce_mean
。总而言之,它看起来像这样:
X = tf.placeholder(tf.float32, shape=(None, None, None, 100))
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1))
X_ = tf.reshape(X, [-1, 100])
Y_ = tf.matmul(X_, W)
X_shape = tf.gather(tf.shape(X), [0,1,2]) # Extract the first three dimensions
target_shape = tf.concat(0, [X_shape, [50]])
Y = tf.reshape(Y_, target_shape)
Y_avg = tf.reduce_mean(Y, 2)
作为GitHub issue you linked suggests, you should use tf.tensordot()
. It enables contraction of axes pairs between two tensors, in line with Numpy's tensordot()
的更名标题。对于您的情况:
X = tf.placeholder(tf.float32, shape=(5, 10, 4, 100))
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1))
Y = tf.tensordot(X, W, [[3], [0]]) # gives shape=[5, 10, 4, 50]
我遇到了一个一直困扰我的问题。跟tf.matmul()
和没有广播有关
我知道 https://github.com/tensorflow/tensorflow/issues/216 上有一个类似的问题,但 tf.batch_matmul()
看起来不像我的情况的解决方案。
我需要将输入数据编码为 4D 张量:
X = tf.placeholder(tf.float32, shape=(None, None, None, 100))
第一个维度是批次的大小,第二个维度是批次中的条目数。
您可以将每个条目想象成多个对象的组合(三维)。最后,每个对象都由一个包含 100 个浮点值的向量来描述。
请注意,我对第二个和第三个维度使用了 None,因为每个批次的实际尺寸可能会发生变化。但是,为简单起见,让我们用实际数字塑造张量:
X = tf.placeholder(tf.float32, shape=(5, 10, 4, 100))
这些是我的计算步骤:
计算每个包含 100 个浮点值的向量的函数(例如,线性函数)
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1))
Y = tf.matmul(X, W)
问题:tf.matmul()
没有广播,使用tf.batch_matmul()
也没有成功 Y 的预期形状:(5, 10, 4, 50)为批次的每个条目应用平均池化(在每个条目的对象上):
Y_avg = tf.reduce_mean(Y, 2)
Y_avg 的预期形状:(5, 10, 50)
我预计 tf.matmul()
会支持广播。然后我发现 tf.batch_matmul()
,但它看起来仍然不适用于我的情况(例如,W 至少需要有 3 个维度,不清楚为什么)。
顺便说一句,上面我使用了一个简单的线性函数(其权重存储在W中)。但在我的模型中,我有一个深层网络。所以,我遇到的更普遍的问题是自动为张量的每个切片计算一个函数。这就是为什么我预计 tf.matmul()
会有广播行为(如果是这样,也许甚至不需要 tf.batch_matmul()
)。
期待向您学习! 阿莱西奥
您可以通过将 X
重塑为 [n, d]
来实现这一点,其中 d
是单个 "instance" 计算的维数(在您的示例中为 100),并且n
是多维对象中这些实例的数量(在您的示例中为 5*10*4=200
)。重塑后,您可以使用 tf.matmul
然后重塑回所需的形状。前三个维度可以变化的事实使这有点棘手,但您可以使用 tf.shape
来确定 运行 时间内的实际形状。最后,您可以执行计算的第二步,这应该是对相应维度的简单 tf.reduce_mean
。总而言之,它看起来像这样:
X = tf.placeholder(tf.float32, shape=(None, None, None, 100))
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1))
X_ = tf.reshape(X, [-1, 100])
Y_ = tf.matmul(X_, W)
X_shape = tf.gather(tf.shape(X), [0,1,2]) # Extract the first three dimensions
target_shape = tf.concat(0, [X_shape, [50]])
Y = tf.reshape(Y_, target_shape)
Y_avg = tf.reduce_mean(Y, 2)
作为GitHub issue you linked suggests, you should use tf.tensordot()
. It enables contraction of axes pairs between two tensors, in line with Numpy's tensordot()
的更名标题。对于您的情况:
X = tf.placeholder(tf.float32, shape=(5, 10, 4, 100))
W = tf.Variable(tf.truncated_normal([100, 50], stddev=0.1))
Y = tf.tensordot(X, W, [[3], [0]]) # gives shape=[5, 10, 4, 50]