【问题标题】:Cartesian Product in TensorflowTensorflow 中的笛卡尔积
【发布时间】:2018-04-18 08:43:19
【问题描述】:

有没有像 itertools.product 这样在 Tensorflow 中做笛卡尔积的简单方法?我想获得两个张量(ab)的元素的组合,在 Python 中,可以通过 itertools 作为list(product(a, b))。我正在寻找 Tensorflow 中的替代方案。

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    我在这里假设ab 都是一维张量。

    要获得两者的笛卡尔积,我会使用tf.expand_dimstf.tile 的组合:

    a = tf.constant([1,2,3]) 
    b = tf.constant([4,5,6,7]) 
    
    tile_a = tf.tile(tf.expand_dims(a, 1), [1, tf.shape(b)[0]])  
    tile_a = tf.expand_dims(tile_a, 2) 
    tile_b = tf.tile(tf.expand_dims(b, 0), [tf.shape(a)[0], 1]) 
    tile_b = tf.expand_dims(tile_b, 2) 
    
    cartesian_product = tf.concat([tile_a, tile_b], axis=2) 
    
    cart = tf.Session().run(cartesian_product) 
    
    print(cart.shape) 
    print(cart) 
    

    您最终得到一个 len(a) * len(b) * 2 张量,其中 ab 的元素的每个组合都在最后一个维度中表示。

    【讨论】:

      【解决方案2】:

      Jaba 的回答让我深受启发。如果你想得到两个二维张量的笛卡尔积,你可以这样做:

      输入a:[N,L]和b:[M,L],得到一个[N*M,L]的concat张量

      tile_a = tf.tile(tf.expand_dims(a, 1), [1, M, 1])  
      tile_b = tf.tile(tf.expand_dims(b, 0), [N, 1, 1]) 
      
      cartesian_product = tf.concat([tile_a, tile_b], axis=2)   
      cartesian = tf.reshape(cartesian_product, [N*M, -1])
      
      cart = tf.Session().run(cartesian) 
      
      print(cart.shape)
      print(cart) 
      

      【讨论】:

      • 如果 a 或 b 为空,这将不起作用,但您可以通过使用 a.shape[-1] + b.shape[-1] 而不是 [N * M, -1] 中的 -1 来修复它
      【解决方案3】:

      一个更短的解决方案,使用tf.add() 进行广播(测试):

      import tensorflow as tf
      
      a = tf.constant([1,2,3]) 
      b = tf.constant([4,5,6,7]) 
      
      a, b = a[ None, :, None ], b[ :, None, None ]
      cartesian_product = tf.concat( [ a + tf.zeros_like( b ),
                                       tf.zeros_like( a ) + b ], axis = 2 )
      
      with tf.Session() as sess:
          print( sess.run( cartesian_product ) )
      

      将输出:

      [[[1 4]
      [2 4]
      [3 4]]

      [[1 5]
      [2 5]
      [3 5]]

      [[1 6]
      [2 6]
      [3 6]]

      [[1 7]
      [2 7]
      [3 7]]]

      【讨论】:

      • 这个答案太棒了!虽然可能不太可读,但它更通用。似乎适用于维度 1 之后的任意维度的张量。例如,它仍然会返回您对 a = tf.constant([[[1,2,3],[4,5,6]],[[1,1,1],[1,1,1]]]) b = tf.constant([[[7,8,9],[10,11,12]]]) 的期望。
      【解决方案4】:
      import tensorflow as tf
      
      a = tf.constant([0, 1, 2])
      b = tf.constant([2, 3])
      c = tf.stack(tf.meshgrid(a, b, indexing='ij'), axis=-1)
      c = tf.reshape(c, (-1, 2))
      with tf.Session() as sess:
          print(sess.run(c))
      

      输出:

      [[0 2]
       [0 3]
       [1 2]
       [1 3]
       [2 2]
       [2 3]]
      

      感谢 jdehesa:link

      【讨论】:

        【解决方案5】:

        Sunreef 的答案更简洁的版本使用 tf.stack 而不是 tf.concat

        a = tf.constant([1,2,3]) 
        b = tf.constant([4,5,6,7]) 
        
        tile_a = tf.tile(tf.expand_dims(a, 1), [1, tf.shape(b)[0]]) 
        tile_b = tf.tile(tf.expand_dims(b, 0), [tf.shape(a)[0], 1])  
        ans = tf.stack([tile_a, tile_b], -1)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-07
          • 2013-08-17
          • 2011-01-29
          • 2019-04-20
          • 2015-03-27
          相关资源
          最近更新 更多