【问题标题】:Tensorflow: Merge two 2-D tensors according to even and odd indicesTensorflow:根据偶数和奇数索引合并两个二维张量
【发布时间】:2017-07-06 15:15:20
【问题描述】:

我想检查批次的偶数和奇数元素,并在需要时交换它们。我设法得到了两个我想要交织的张量:

def tf_oplu(x, name=None):   


    even = x[:,::2] #slicing into odd and even parts on the batch
    odd = x[:,1::2]

    even_flatten = tf.reshape(even, [-1]) # flatten tensors 
    #in row-major order to apply function across them

    odd_flatten = tf.reshape(odd, [-1])

    compare = tf.to_float(even_flatten<odd_flatten)
    compare_not = tf.to_float(even_flatten>=odd_flatten)

    #def oplu(x,y): # trivial function  
    #    if x<y : # (x<y)==1
    #       return y, x 
    #    else:
    #       return x, y # (x<y)==0

    even_flatten_new = odd_flatten * compare + even_flatten * compare_not
    odd_flatten_new = odd_flatten * compare_not + even_flatten * compare

    # convolute back 

    even_new = tf.reshape(even_flatten_new,[100,128])
    odd_new = tf.reshape(odd_flatten_new,[100,128])

现在我想返回填充了偶数和奇数位的 $[100,256]$ 张量。在 numpy 中,我当然会这样做:

y = np.empty((even_new.size + odd_newsize,), dtype=even_new.dtype)
y[:,0::2] = even_new
y[:,1::2] = odd_new

return y   

但是对于 tensoflow 来说这样的事情是不可能的,因为张量是不可修改的。我想sparse tensortf.gather_nd 都可以,但两者都需要生成索引数组,这对我来说又是一项不平凡的任务。 还有一点需要注意:我不想通过tf.py_func 使用任何python 函数,因为我检查了它们是否仅在CPU 上运行。也许 lambda 和 tf.map_fn 可能会有所帮助?谢谢!

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    要垂直交错两个矩阵,你不需要像gathermap_fn 这样的大炮。您可以简单地将它们交错如下:

    tf.reshape(
      tf.stack([even_new, odd_new], axis=1),
      [-1, tf.shape(even_new)[1]])
    

    编辑

    水平交错:

    tf.reshape(
      tf.concat([even_new[...,tf.newaxis], odd_new[...,tf.newaxis]], axis=-1), 
      [tf.shape(even_new)[0],-1])
    

    这个想法是使用堆栈将它们交错在内存中。堆栈发生的维度给出了交错的粒度。如果我们在axis=0 处堆叠,则交错发生在每个元素处,混合列。如果我们在axis=1 堆叠,整个输入行保持连续,行之间发生交错。

    【讨论】:

    • 非常感谢!但是这段代码生成张量 [200,128] 而不是 [100,256]。我已将其更改为y = tf.reshape(tf.stack([even_new, odd_new], axis=0), [tf.shape(even_new)[0],-1]),因此输出符合预期。你能否给我解释一下为什么它确实在需要的地方放置了偶数和奇数元素?
    • 据我了解,它将它们垂直堆叠,然后重新整形,应该将水平放置的元素放在一起。
    • 是的,我按照您的 numpy 示例进行操作,该示例还垂直堆叠张量(沿第一维)。您将它们水平堆叠的修改是正确的。
    • 哦,抱歉 - 打错字了,我的意思是 y[:, ::2]y[:,1::2]
    • @Slowpoke 对不起,你是对的,我应该更好地检查你的公式。我建议你一个新的公式,它不是基于transpose,这在某种程度上是一个重量级的操作。告诉我进展如何。
    【解决方案2】:

    您可以使用tf.dynamic_stitch,它将每个要交错的张量的索引张量列表作为第一个参数,并将要交错的张量列表作为第二个参数。张量将沿第一维交错,因此我们需要转置它们,然后转回。代码如下:

    even_new = tf.transpose(even_new,perm=[1,0])
    odd_new = tf.transpose(odd_new,perm=[1,0])
    even_pos = tf.convert_to_tensor(list(range(0,256,2)),dtype=tf.int32)
    odd_pos = tf.convert_to_tensor(list(range(1,256,2)),dtype=tf.int32)
    interleaved = tf.dynamic_stitch([even_pos,odd_pos],[even_new,odd_new])
    interleaved = tf.transpose(interleaved,perm=[1,0])
    

    【讨论】:

      【解决方案3】:

      您可以使用assign 分配到切片中。

      odd_new = tf.constant([1,3,5])
      even_new = tf.constant([2,4,6])
      y=tf.Variable(tf.zeros(6, dtype=tf.int32))
      
      sess = tf.InteractiveSession()
      sess.run(tf.global_variables_initializer())
      y[0::2].assign(odd_new).eval()
      y[1::2].assign(even_new).eval()
      

      【讨论】:

      • 非常感谢!我最初尝试使用分配运算符 but faced some problems and was discouraged from doing it 构建我的网络(但是,我认为代码是正确的),所以现在我更喜欢使用嵌入式 tensorflow 函数,所以第一个答案适合我。不过还是谢谢!
      猜你喜欢
      • 2019-09-15
      • 2015-06-30
      • 2018-08-09
      • 1970-01-01
      • 2020-01-03
      • 2015-10-28
      • 1970-01-01
      • 2019-07-15
      • 2020-09-26
      相关资源
      最近更新 更多