为什么增加张量的维数可以实现逐元素减法?

时间:2017-04-07 23:59:38

标签: python numpy tensorflow

见到这里: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)

为什么这个元素减法?这是如何工作的?

1 个答案:

答案 0 :(得分:1)

你在这里看到的是张量(或数组)Broadcasting的影响。

在tensorflow / numpy中,减法始终是逐个元素的。您的第一个减法不起作用,因为操作数具有形状(10,2)(4,2),它们不是兼容。当您扩展尺寸时,形状变得兼容。

操作数矩阵的形状可能不同,但需要兼容元素操作才能工作。

对于要兼容的形状,形状在尾部/最后一个维度对齐,然后每两个相应的尺寸必须兼容。如果符合以下条件,则两个维度兼容:

  
      
  1. 他们是平等的,或

  2.   
  3. 其中一个是1(“退化”维度)

  4.   

例如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