【问题标题】:Tensorflow tf.map_fn errorsTensorFlow tf.map_fn 错误
【发布时间】:2019-12-14 03:08:50
【问题描述】:
    a = tf.constant([[1, 2, 3, 1], [4, 5, 6, 1], [7, 8, 9, 1]])
    mul = tf.constant([1, 3, 2])
    result = []
    for i in range(3):
        print(a[i], mul[i])
        result.append(tf.tile(a[i], [mul[i]]))

    with tf.Session() as sess:
        print([r.eval() for r in result])

正确结果:

[数组([1, 2, 3, 1]), 数组([4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1]), 数组([7 , 8, 9, 1, 7, 8, 9, 1])]

while run below with tf.map_fn, it will fail
    c = tf.constant([[1, 2, 3, 1], [4, 5, 6, 1], [7, 8, 9, 1]])
    x = tf.constant([1, 3, 1])

    def cc(b, t):
        print(b.shape, t)
        print(type(b), type(t))
        return tf.tile(b, [t])


    d = tf.map_fn(fn=lambda t: cc(t[0], t[1]), elems=(c, x))

这是错误跟踪:

Traceback(最近一次调用最后一次): 文件“C:\Program Files\Python36\lib\site-packages\tensorflow\python\util\nest.py”,第 297 行,位于 assert_same_structure expand_composites) ValueError: 这两个结构没有相同的嵌套结构。

第一个结构:

type=tuple str=(tf.int32, tf.int32)

第二个结构:

type=Tensor str=Tensor("map/while/Tile:0", shape=(?,), dtype=int32)

更具体地说:子结构"type=tuple str=(tf.int32, tf.int32)" 是一个序列,而子结构"type=Tensor str=Tensor("map/while/Tile:0", shape=(?,), dtype=int32)" 不是

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    tf.map_fn 无法处理您的情况。基本上,每次执行操作后,它都需要一致的形状输出。让我们举个例子。 tf.map_fn 将执行以下操作。

    map => [1,2,3,1], [1] => returns a 4 element long vector
    map => [4,5,6,1], [3] => returns a 12 element long vector
    map => [7,8,9,1], [2] => returns a 8 element long vector
    

    因此,当 map_fn 检查每一行的输出时,它会发现形状不一致。这就是错误所在。

    因此,为此,您唯一的选择(据我所知)是使用tf.unstack(如果使用 TF 1.x),这相当于在 TF 2.0 中迭代行(您问题中的第一种方法)。

    如果你需要它在最后成为一个张量,你可以将它作为RaggedTensor

    c = tf.constant([[1, 2, 3, 1], [4, 5, 6, 1], [7, 8, 9, 1]])
    x = tf.constant([1, 3, 2])
    
    def cc(b, t):
        return tf.tile(b, [t])
    
    unstack_c = tf.unstack(c)
    unstack_x = tf.unstack(x)
    
    vals = []
    for rc, rx in zip(unstack_c, unstack_x):
      vals.append(tf.reshape(cc(rc, rx),[1,-1]))
    
    res = tf.ragged.stack(vals)
    

    【讨论】:

    • 感谢您指出根本原因。我尝试了你的解决方案,它在我的情况下对我有用,因为张量 c 和张量 x 是常数张量。但是,当使用 tf.placeholder([None, None, 3]) tf.placeholder([None, None]) 定义 c 和 x 时,它不起作用。 c 和 x 的第一个 dim 是 None ,即 batch_size,c 和 x None 的第二个 dim 对两者都是相同的,例如 c shape [1, 3,10] ,x :shape [1,3] 。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2020-10-19
    • 2017-08-30
    • 2016-02-16
    • 2017-08-16
    • 2018-09-01
    相关资源
    最近更新 更多