见到这里:https://gist.github.com/narphorium/d06b7ed234287e319f18
这是可重现的代码:
import numpy as np
import tensorflow as tf
points = np.random.random_sample((10,2))
tf_points = tf.constant(points)
slice = tf.slice(tf_points,[0,0],[4,-1])
print tf.subtract(tf_points,slice).get_shape() #This errors out because the dimensions are incorrect
tf_points_expanded = tf.expand_dims(tf_points,0)
slice_expanded = tf.expand_dims(slice,1)
print tf.subtract(tf_points_expanded,slice_expanded).get_shape() #This works and prints (4,10,2)
为什么这个元素减法?这是如何工作的?
答案 0 :(得分:1)
你在这里看到的是张量(或数组)Broadcasting的影响。
在tensorflow / numpy中,减法始终是逐个元素的。您的第一个减法不起作用,因为操作数具有形状(10,2)
和(4,2)
,它们不是兼容。当您扩展尺寸时,形状变得兼容。
操作数矩阵的形状可能不同,但需要兼容元素操作才能工作。
对于要兼容的形状,形状在尾部/最后一个维度对齐,然后每两个相应的尺寸必须兼容。如果符合以下条件,则两个维度兼容:
他们是平等的,或
- 醇>
其中一个是1(“退化”维度)
例如np.zeros((5,1,2)) - np.ones((3,1))
有效,因为形状兼容:
5 1 2
3 1
^ aligned at the trailing dimension
它的工作方式是,对于每个维度(从最后一个开始),该维度中较小尺寸的矩阵将沿着该维度重复以匹配另一个矩阵。在此示例中,对于最后一个维度,(3,1)
矩阵需要在最后一个维度重复为(3,2)
。然后,对于倒数第二个维度,需要重复(5,1,2)
成为(5,3,2)
。最后,(3,2)
矩阵沿着新的第一维重复5次,也变为(5,3,2)
。然后正常地执行元素减法。
在您的示例中,对不兼容的形状(10,2)
和(4,2)
进行减法会产生错误。但在将尺寸扩展到(1,10,2)
和(4,1,2)
后,它们会根据上述规则变得兼容:
1 10 2
4 1 2