【问题标题】:What do I use instead of tf.decode_raw for variable length strings?对于可变长度字符串,我应该使用什么来代替 tf.decode_raw?
【发布时间】:2018-01-24 02:06:48
【问题描述】:

我有一个特征列,它只是一个字符串:

tf.FixedLenFeature((), tf.string)

我的图表使用tf.decode_raw 将张量转换为二进制:

tf.decode_raw(features['text'], tf.uint8)

这适用于 batch_size = 1,但当字符串长度不同时,batch_size > 1 会失败。 decode_raw 抛出 DecodeRaw requires input strings to all be the same size

是否有替代 tf.decode_raw 的方法来返回填充张量和字符串的长度?

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    我会使用tf.data.Dataset。启用急切执行:

    import tensorflow as tf
    import tensorflow.contrib.eager as tfe
    tfe.enable_eager_execution()
    
    def _decode_and_length_map(encoded_string):
      decoded = tf.decode_raw(encoded_string, out_type=tf.uint8)
      return decoded, tf.shape(decoded)[0]
    
    inputs = tf.constant(["aaa", "bbbbbbbb", "abcde"], dtype=tf.string)
    dataset = (tf.data.Dataset.from_tensor_slices(inputs)
               .map(_decode_and_length_map)
               .padded_batch(batch_size=2, padded_shapes=([None], [])))
    iterator = tfe.Iterator(dataset)
    print(iterator.next())
    print(iterator.next())
    

    打印(免责声明:手动重新格式化)

    (<tf.Tensor: id=24, shape=(2, 8), dtype=uint8,
         numpy=array([[97, 97, 97,  0,  0,  0,  0,  0],
                      [98, 98, 98, 98, 98, 98, 98, 98]], dtype=uint8)>,
     <tf.Tensor: id=25, shape=(2,), dtype=int32, numpy=array([3, 8], dtype=int32)>)
    
    (<tf.Tensor: id=28, shape=(1, 5), dtype=uint8, 
         numpy=array([[ 97,  98,  99, 100, 101]], dtype=uint8)>,
     <tf.Tensor: id=29, shape=(1,), dtype=int32, numpy=array([5], dtype=int32)>)
    

    当然你可以混合和匹配数据源,添加随机化,改变填充字符等等。

    也适用于图形构建:

    import tensorflow as tf
    
    def _decode_and_length_map(encoded_string):
      decoded = tf.decode_raw(encoded_string, out_type=tf.uint8)
      return decoded, tf.shape(decoded)[0]
    
    inputs = tf.constant(["aaa", "bbbbbbbb", "abcde"], dtype=tf.string)
    dataset = (tf.data.Dataset.from_tensor_slices(inputs)
               .map(_decode_and_length_map)
               .padded_batch(batch_size=2, padded_shapes=([None], [])))
    batch_op = dataset.make_one_shot_iterator().get_next()
    with tf.Session() as session:
      print(session.run(batch_op))
      print(session.run(batch_op))
    

    【讨论】:

    • 这看起来完全符合我的要求,所以请投票,谢谢!但是 Eager 模式是否适用于 tf.estimator.Estimator?我没有考虑这部分,因为我没有意识到它是相关的。
    • 不幸的是还没有;您需要坚持使用 model_fn 中的图形构建版本。
    • 根据stackoverflow.com/a/44504063/129889,看来我应该改用make_initializable_iterator()。正在尝试……
    • 刚刚意识到应该是input_fn。如果您将此位折叠到现有的输入管道(单个数据集)中,错误可能会消失,然后从中创建一个Iterator
    • 哦,非常感谢您的指正。那行得通!我添加了一个 Dataset.map() 通过调整您的_decode_and_length_mapfeatures['text'] 扩展为features['text_bytes']features['text_length'],然后使用padded_batch(batch_size, padded_shapes = ({'text_bytes': (None,), 'text_length': ()}, ()))
    猜你喜欢
    • 1970-01-01
    • 2010-11-05
    • 2010-12-06
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多