【问题标题】:tensorflow map_fn TensorArray has inconsistent shapestensorflow map_fn TensorArray 的形状不一致
【发布时间】:2017-04-07 06:09:51
【问题描述】:

我正在使用 map_fn 函数,并注意到它输出一个 TensorArray,这应该意味着它能够输出“锯齿状”张量(其中内部的张量具有不同的第一维。

我试图用这段代码来看看这个:

import tensorflow as tf
import numpy as np

NUM_ARRAYS = 1000
MAX_LENGTH = 1000

lengths = tf.placeholder(tf.int32)
tArray = tf.map_fn(lambda x: tf.random_normal((x,), 0, 1),
                   lengths,
                   dtype=tf.float32) # Should return a TensorArray.

# startTensor =  tf.random_normal((tf.reduce_sum(lengths),), 0, 1)
# tArray = tf.TensorArray(tf.float32, NUM_ARRAYS)
# tArray = tArray.split(startTensor, lengths)
# outArray = tArray.concat()


with tf.Session() as sess:
    outputArray, l = sess.run(
        [tArray, lengths],
        feed_dict={lengths: np.random.randint(MAX_LENGTH, size=NUM_ARRAYS)})
    print outputArray.shape, l

但是得到了错误:

“TensorArray 的形状不一致。索引 0 的形状:[259] 但索引 1 的形状:[773]”

这当然让我感到惊讶,因为我的印象是 TensorArrays 应该能够处理它。我错了吗?

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    虽然tf.map_fn() 确实使用tf.TensorArray 对象在内部,并且tf.TensorArray 可以容纳不同大小的对象,但该程序无法按原样工作,因为tf.map_fn() 将其转换为通过将元素堆叠在一起,tf.TensorArray 结果返回到tf.Tensor,正是这个操作失败了。

    但是,您可以使用较低的tf.while_loop() 操作来实现基于tf.TensorArray 的操作:

    lengths = tf.placeholder(tf.int32)
    num_elems = tf.shape(lengths)[0]
    init_array = tf.TensorArray(tf.float32, size=num_elems)
    
    def loop_body(i, ta):
      return i + 1, ta.write(i, tf.random_normal((lengths[i],), 0, 1))
    
    _, result_array = tf.while_loop(
        lambda i, ta: i < num_elems, loop_body, [0, init_array])
    

    【讨论】:

      【解决方案2】:

      基于 mrry 的回答,还有一些可以在 TF2.x 下运行的示例

      import tensorflow as tf
      # ================= example 1 ==================
      num_elems = 5
      init_array = tf.TensorArray(tf.float32, size=num_elems, infer_shape=False)
      lengths = tf.range(0, 5)
      def loop_body(i, ta):
        return i + 1, ta.write(i, tf.random.normal((lengths[i],), 0, 1))
      
      _, result_array = tf.while_loop(
          lambda i, ta: i < num_elems, loop_body, [0, init_array])
      
      for i in range(num_elems):
          print(result_array.read(i))
      
      # ================== example 2 ==================
      # TensorArray whose size is known at run time and shapes of elements
      # are not necessarily the same
      ta = tf.TensorArray(tf.float32, size=0, dynamic_size=True, infer_shape=False)
      
      # init ta with some mock data
      ta = ta.write(0, 0.0)
      ta = ta.write(1, 1.0)
      ta = ta.write(2, tf.constant([2.0, 2.0]))
      
      # loop body
      def loop_body(i, t):
          val = t.read(i)
          # do something
          t = t.write(i, tf.multiply(2.0, val))
          return i+1, t
      
      # stop condition for while loop
      index = tf.constant(0)
      cond = lambda i, t: tf.less(i, t.size())
      
      # results
      i = tf.constant(0)
      _, result_array = tf.while_loop(cond, loop_body, [i, ta])
      
      for i in range(result_array.size()):
          print(result_array.read(i))
      

      【讨论】:

        猜你喜欢
        • 2022-06-13
        • 2017-05-07
        • 2017-09-27
        • 2018-11-23
        • 1970-01-01
        • 1970-01-01
        • 2018-01-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多