TensorFlow Estimator中from_generator的TensorShape设置方法咨询
核心问题分析
你遇到的错误根源是对from_generator的output_shapes参数理解偏差:这个参数定义的是生成器每次yield的单个样本的形状,而非batch处理后的张量形状。
你的生成器gen(n)每次返回的都是三个标量:
ii是整数标量(形状())'t{0}'.format(ii)是字符串标量(形状())ii*2是浮点标量(形状())
但你一开始设置了([None], [None], [None]),这相当于告诉TensorFlow“生成器每次返回的是三个一维未知长度的张量”,也就是期望每个元素形状是(?,),但实际生成器给出的是标量(),自然就触发了形状不匹配的错误。
正确的设置方式
既然每个yield的元素都是标量,output_shapes应该设置为([], [], []),对应三个标量的形状。修改你的input_fn里的from_generator调用即可:
def input_fn(n): # 将output_shapes从[None]改为[],匹配单个标量的形状 ds = tf.data.Dataset.from_generator(lambda: gen(n), (tf.int64, tf.string, tf.float32), ([], [], [])) ds = ds.batch(10) x, y, z = ds.make_one_shot_iterator().get_next() return {'x': x, 'y': y}, tf.greater_equal(z, 10)
为什么这样能解决问题?
当你调用ds.batch(10)时,TensorFlow会自动把10个标量元素堆叠成形状为(10,)的张量,此时迭代器返回的x、y、z的形状就是(10,),刚好符合Estimator对批量输入的要求。
补充说明:如果你的生成器每次返回的是一维数组(比如yield [ii, ii+1], 't{0}'.format(ii), [ii*2, ii*3]),那你才需要用[None]来表示这个一维数组的长度可变,此时output_shapes就应该设为([None], [], [None])。
对应错误栈的解释
错误栈里的提示:
ValueError:
generatoryielded an element of shape () where an element of shape (?,) was expected.
就是在明确提示你:生成器返回的元素是标量形状(),但你设置的output_shapes要求元素是一维未知长度的(?,),两者不匹配。
内容的提问来源于stack exchange,提问作者Feng Tian

