【问题标题】:Tensorflow unsorted_segment_sum dimensionTensorFlow unsorted_segment_sum 维度
【发布时间】:2017-08-29 19:39:36
【问题描述】:

我正在使用 TensorFlow 的 tf.unsorted_segment_sum 方法,当我作为数据提供的张量只有一行时,它可以正常工作。例如:

tf.unsorted_segment_sum(tf.constant([0.2, 0.1, 0.5, 0.7, 0.8]),
                        tf.constant([0, 0, 1, 2, 2]), 3)

给出正确的结果:

array([ 0.3,  0.5 , 1.5 ], dtype=float32)

问题是,如果我使用多行的张量,我如何才能得到每行的结果?例如,如果我尝试使用两行的张量:

tf.unsorted_segment_sum(tf.constant([[0.2, 0.1, 0.5, 0.7, 0.8],
                                     [0.2, 0.2, 0.5, 0.7, 0.8]]),
                        tf.constant([[0, 0, 1, 2, 2],
                                     [0, 0, 1, 2, 2]]), 3)

我期望的结果是:

array([ [ 0.3,  0.5 , 1.5 ], [ 0.4, 0.5, 1.5 ] ], dtype=float32)

但我得到的是:

array([ 0.7,  1. ,  3. ], dtype=float32)

我想知道是否有人知道如何在不使用 for 循环的情况下获取每一行的结果?

提前致谢

【问题讨论】:

    标签: tensorflow sum segment


    【解决方案1】:

    编辑:

    虽然下面的解决方案可能会涵盖一些额外的奇怪用途,但只需通过转置数据就可以更轻松地解决这个问题。事实证明,即使tf.unsorted_segment_sum 没有axis 参数,它也只能沿一个轴工作,只要它是第一个轴。所以你可以这样做:

    import tensorflow as tf
    
    with tf.Session() as sess:
        data = tf.constant([[0.2, 0.1, 0.5, 0.7, 0.8],
                            [0.2, 0.2, 0.5, 0.7, 0.8]])
        idx = tf.constant([0, 0, 1, 2, 2])
        result = tf.transpose(tf.unsorted_segment_sum(tf.transpose(data), idx, 3))
        print(sess.run(result))
    

    输出:

    [[ 0.30000001  0.5         1.5       ]
     [ 0.40000001  0.5         1.5       ]]
    

    原帖:

    tf.unsorted_segment_sum 不支持在单轴上工作。最简单的解决方案是将操作应用于每一行,然后将它们连接回来:

    data = tf.constant([[0.2, 0.1, 0.5, 0.7, 0.8],
                        [0.2, 0.2, 0.5, 0.7, 0.8]])
    segment_ids = tf.constant([[0, 0, 1, 2, 2],
                               [0, 0, 1, 2, 2]])
    num_segments = 3
    rows = []
    for data_i, ids_i in zip(data, segment_ids):
        rows.append(tf.unsorted_segment_sum(data_i, ids_i))
    result = tf.stack(rows, axis=0)
    

    但是,这有缺点:1) 它仅适用于静态形状的张量(即,您需要有固定数量的行)和 2) 它可能效率不高。第一个可以使用tf.while_loop 来规避,但是它会很复杂,而且还需要您将行逐一连接,这是非常低效的。另外,您已经说过要避免循环。

    更好的选择是为每一行使用不同的 ID。例如,您可以将segment_id 中的每个值添加到num_segments * row_index,这样您就可以保证每一行都有自己的一组ID:

    num_rows = tf.shape(segment_ids)[0]
    rows_idx = tf.range(num_rows)
    segment_ids_per_row = segment_ids + num_segments * tf.expand_dims(rows_idx, axis=1)
    

    然后你可以应用操作和重塑来获得你想要的张量:

    seg_sums = tf.unsorted_segment_sum(data, segment_ids_per_row,
                                       num_segments * num_rows)
    result = tf.reshape(seg_sums, [-1, num_segments])
    

    输出:

    array([[ 0.3, 0.5, 1.5 ],
           [ 0.4, 0.5, 1.5 ]], dtype=float32)
    

    【讨论】:

    • 感谢您的帮助!
    • @user3575801 我更新了答案,实际上这可以更容易地解决(我不知道是否总是这样,或者它是 TensorFlow 中的一个更新的功能......)。
    猜你喜欢
    • 2016-11-18
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多