Python Tensorflow:奇怪的广播行为
我不太了解Tensorflow中的广播机制是如何工作的。假设我们有以下代码:Python Tensorflow:奇怪的广播行为,python,tensorflow,deep-learning,Python,Tensorflow,Deep Learning,我不太了解Tensorflow中的广播机制是如何工作的。假设我们有以下代码: W1_shape = [5, 5, 1, 32] b1_shape = [32] x = tf.placeholder(tf.float32) initial_W1 = tf.truncated_normal(shape=W1_shape, stddev=0.1) W1 = tf.Variable(initial_W1) initial_b1 = tf.constant(0.1, shape=b1_shape) b1
W1_shape = [5, 5, 1, 32]
b1_shape = [32]
x = tf.placeholder(tf.float32)
initial_W1 = tf.truncated_normal(shape=W1_shape, stddev=0.1)
W1 = tf.Variable(initial_W1)
initial_b1 = tf.constant(0.1, shape=b1_shape)
b1 = tf.Variable(initial_b1)
conv1 = tf.nn.conv2d(x, W1, strides=[1, 1, 1, 1], padding='SAME')
conv1_sum = conv1 + b1
y = tf.placeholder(tf.float32)
z = conv1 + y
sess = tf.Session()
# Run init ops
init = tf.global_variables_initializer()
sess.run(init)
while True:
samples, labels, indices = dataset.get_next_batch(batch_size=1000)
samples = samples.reshape((1000, MnistDataSet.MNIST_SIZE, MnistDataSet.MNIST_SIZE, 1))
y_data = np.ones(shape=(1000, 32))
conv1_res, conv1_sum_res, b1_res, z_res=\
sess.run([conv1, conv1_sum, b1, z], feed_dict={x: samples, y: y_data})
if dataset.isNewEpoch:
break
因此,我加载MNIST数据集,它由28x28大小的图像组成。卷积运算符使用32个5x5大小的过滤器。我使用的批量大小为1000,因此数据张量x
的形状为(1000,28,28,1)。tf.nn.conv2d
操作输出形状的张量(1000,28,28,32)y
是一个占位符,我将它添加到(1000,28,28,32)形的conv1
tensor,以检查Tensorflow的广播机制。在y_data=np.one(shape=(1000,32))
行中,我对y
的各种张量形状进行了实验。形状(28,28)、(1000,28)和(1000,32)不会添加到conv1
,类型错误如下:
InvalidArgumentError(回溯见上文):不兼容的形状:[1000,28,28,32]与[28,28]
形状(28,32)和(28,28,32)正确工作并广播。但根据中解释的广播语义,前三种形状也必须起作用,因为它们的顺序是正确的,通过将维度与4D
conv1
张量相匹配。例如,(28,28)匹配维度1和维度2中的(1000,28,28,32),(1000,32)匹配维度0和维度3,如链接中所述。我是不是遗漏了什么或者误解了什么?在这种情况下,Tensorflow的正确广播行为是什么?没错,文档似乎在暗示你所说的。但它看起来像是遵循了numpy broadcsting规则:
在两个阵列上操作时,NumPy会比较它们的形状
元素方面。它从后面的尺寸标注开始,然后开始工作
前进的道路。在以下情况下,两个维度是兼容的:
- (28,28)不能广播到(1000,28,28,32),但(28,28,1)可以
- (1000,28)不能,但(1000,1,28,1)或(1000,28,1,1)可以
- (28,32)之所以有效,是因为尾部尺寸匹配