【问题标题】:How to merge two dimensions of a tensor without assuming the shape of it如何在不假设其形状的情况下合并张量的两个维度
【发布时间】:2019-10-07 11:14:45
【问题描述】:

让我们假设以下函数:

from tensorflow.python.keras import backend as K

def broadcast_sum(a, b):
    a = K.expand_dims(a, 1)
    b = K.expand_dims(b, 2)
    c = a + b
    cs = K.shape(c)
    return K.reshape(c, (cs[0], -1, cs[-1]))

给定两个形状张量(1, 3, 2)(1, 4, 2),它正确返回:

>>> broadcast_sum(K.placeholder((1, 3, 2)), K.placeholder((1, 4, 2)))
>>> <tf.Tensor 'Reshape_2:0' shape=(1, 12, 2) dtype=float32>

目前,此功能仅适用于 3D 输入(因为 reshape 行)。我的问题是,如何在不知道形状的情况下使用任何形状(使用相同的功能)?当然,我假设输入具有相同的形状并且至少是 3D。但是我如何才能拥有一个适用于 3D、4D 等的函数呢?

我假设函数将广播的始终是第二个维度(从左起),其余维度在两个输入之间是相同的。以下是我想要使用相同功能的形状:

>>> broadcast_sum(K.placeholder((1, 3, 5, 2)), K.placeholder((1, 4, 5, 2)))
>>> <tf.Tensor 'Reshape_3:0' shape=(1, 60, 2) dtype=float32>

当然,现在返回的张量是错误的。它的形状应该是(1, 12, 5, 2)

[更新]

还请考虑第一个维度(批量大小)可能是None。事实上,除了最右边的维度之外的任何维度都可以是None

【问题讨论】:

    标签: tensorflow keras tensor


    【解决方案1】:

    我假设它始终是第二维(从左至右) 该函数将广播,其余维度为 两个输入之间相同。

    基于此,我重用了其中一个输入的形状信息。

    from tensorflow.python.keras import backend as K
    def broadcast_sum(a, b):
        final_shape = (a.shape[0], -1, *a.shape[2:])
        a = K.expand_dims(a, 1)
        b = K.expand_dims(b, 2)
        c = a + b
        return K.reshape(c, final_shape)
    
    
    print(broadcast_sum(K.placeholder((1, 3, 2)), K.placeholder((1, 4, 2))))
    print(broadcast_sum(K.placeholder((1, 3, 5, 2)), K.placeholder((1, 4, 5, 2))))
    
    Tensor("Reshape:0", shape=(1, 4, 3, 2), dtype=float32)
    Tensor("Reshape_1:0", shape=(1, 12, 5, 2), dtype=float32)
    

    【讨论】:

    • 谢谢,虽然这有帮助,但我必须坚持使用K.shape(),因为批量大小维度可能是None。如果是这样,您的解决方案将无法正常工作。
    • 事实上,现在我想起来,任何尺寸(除了最右边的)都可以是None。我希望我能想出一个解决方案,它依赖于操纵K.shape() 的返回值,所以它一直有效(只要提供最右边的维度)。
    猜你喜欢
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 2019-08-07
    • 1970-01-01
    • 2021-11-12
    • 2017-06-24
    • 1970-01-01
    • 2021-12-09
    相关资源
    最近更新 更多