Tensorflow tf.map_fn错误

时间:2019-12-14 03:08:50

标签: python tensorflow

    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])

正确的结果:

[array([1、2、3、1]),array([4、5、6、1、4、5、6、1、4、5、6、1]),array([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))

这是错误跟踪:

  

回溯(最近通话最近):     在assert_same_structure中的第297行中的文件“ C:\ Program Files \ Python36 \ lib \ site-packages \ tensorflow \ python \ util \ nest.py”       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)“是不是

1 个答案:

答案 0 :(得分:0)

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)