【问题标题】:Tensorflow: Load unknown TFRecord datasetTensorflow:加载未知的 TFRecord 数据集
【发布时间】:2019-07-10 00:45:57
【问题描述】:

我得到了一个 TFRecord 数据文件filename = train-00000-of-00001,其中包含未知大小的图像以及可能还有其他信息。我知道我可以使用dataset = tf.data.TFRecordDataset(filename) 打开数据集。

如何从该文件中提取图像以将其保存为 numpy-array?

我也不知道TFRecord文件中是否保存了任何其他信息,例如标签或分辨率。我怎样才能得到这些信息?如何将它们保存为 numpy-array?

我通常只使用 numpy-arrays 并且不熟悉 TFRecord 数据文件。

【问题讨论】:

    标签: tensorflow tensorflow-datasets


    【解决方案1】:

    1.) 如何从该文件中提取图像以将其保存为 numpy-array?

    你要找的是这个:

    record_iterator = tf.python_io.tf_record_iterator(path=filename)
    
    for string_record in record_iterator:
      example = tf.train.Example()
      example.ParseFromString(string_record)
    
      print(example)
    
      # Exit after 1 iteration as this is purely demonstrative.
      break
    

    2.) 我如何获得这些信息?

    这里是官方documentation。我强烈建议您阅读文档,因为它逐步介绍了如何提取您正在寻找的值。

    基本上,您必须将example 转换为字典。因此,如果我想找出 tfrecord 文件中包含哪些类型的信息,我会这样做(在第一个问题中所述代码的上下文中):dict(example.features.feature).keys()

    3.) 如何将它们保存为 numpy-array?

    我会建立在上面提到的 for 循环之上。因此,对于每个循环,它都会提取您感兴趣的值并将它们附加到 numpy 数组中。如果需要,您可以从这些数组中创建一个 pandas 数据框并将其保存为 csv 文件。

    但是……

    您似乎有多个 tfrecord 文件...tf.data.TFRecordDataset(filename) 返回一个用于训练模型的数据集。

    因此,如果有多个 tfrecord,您将需要一个双 for 循环。外循环将遍历每个文件。对于该特定文件,内部循环将遍历所有 tf​​.examples。

    编辑:

    转换为 np.array()

    import tensorflow as tf
    from PIL import Image
    import io
    
    for string_record in record_iterator:
      example = tf.train.Example()
      example.ParseFromString(string_record)
    
      print(example)
    
      # Get the values in a dictionary
      example_bytes = dict(example.features.feature)['image_raw'].bytes_list.value[0]
      image_array = np.array(Image.open(io.BytesIO(example_bytes)))
      print(image_array)
      break
    

    以上代码的来源:

    PIL的官方文档

    编辑 2:

    import tensorflow as tf
    from PIL import Image
    import io
    import numpy as np
    
    # Load image
    cat_in_snow  = tf.keras.utils.get_file(path, 'https://storage.googleapis.com/download.tensorflow.org/example_images/320px-Felis_catus-cat_on_snow.jpg')
    
    #------------------------------------------------------Convert to tfrecords
    def _bytes_feature(value):
      """Returns a bytes_list from a string / byte."""
      return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
    
    def image_example(image_string):
      feature = {
          'image_raw': _bytes_feature(image_string),
      }
      return tf.train.Example(features=tf.train.Features(feature=feature))
    
    with tf.python_io.TFRecordWriter('images.tfrecords') as writer:
        image_string = open(cat_in_snow, 'rb').read()
        tf_example = image_example(image_string)
        writer.write(tf_example.SerializeToString())
    #------------------------------------------------------
    
    
    #------------------------------------------------------Begin Operation
    record_iterator = tf.python_io.tf_record_iterator(path to tfrecord file)
    
    for string_record in record_iterator:
      example = tf.train.Example()
      example.ParseFromString(string_record)
    
      print(example)
    
      # OPTION 1: convert bytes to arrays using PIL and IO
      example_bytes = dict(example.features.feature)['image_raw'].bytes_list.value[0]
      PIL_array = np.array(Image.open(io.BytesIO(example_bytes)))
    
      # OPTION 2: convert bytes to arrays using Tensorflow
      with tf.Session() as sess:
          TF_array = sess.run(tf.image.decode_jpeg(example_bytes, channels=3))
    
      break
    #------------------------------------------------------
    
    
    #------------------------------------------------------Compare results
    (PIL_array.flatten() != TF_array.flatten()).sum()
    PIL_array == TF_array
    
    PIL_img = Image.fromarray(PIL_array, 'RGB')
    PIL_img.save('PIL_IMAGE.jpg')
    
    TF_img = Image.fromarray(TF_array, 'RGB')
    TF_img.save('TF_IMAGE.jpg')
    #------------------------------------------------------
    
    • 请记住,tfrecords 只是存储 TensorFlow 模型以高效读取信息的一种方式。

    • 我使用 PIL 和 IO 基本上将字节转换为图像。 IO 获取字节并将它们转换为 PIL.Image 可以读取的file like object

    • 是的,有一个纯tensorflow的方式来做到这一点:tf.image.decode_jpeg
    • 是的,当您比较两个数组时,这两种方法之间存在差异
    • 您应该选择哪一个?如果您担心Tensorflow's github 中所述的准确性:“TensorFlow 选择的 jpeg 解码默认值是 IFAST,牺牲图像质量来换取速度”,那么 Tensorflow 不是最佳选择。此信息的信用属于此post

    【讨论】:

    • 在您的帮助下,我现在可以看到每个示例都包含几个features,它们都有一个key 和一个value。这些键是label、image/encoded、image/width 和image/height。我仍然不清楚如何读取这些信息以及如何将编码图像转换为尺寸为WxHxC 的矩阵。
    • 是的,它是一个字节列表。
    • 太棒了!现在我可以提取图像了。但是,我不明白它为什么起作用。为什么我必须加载PIL 和io?这些库到底是做什么的?有没有一种纯粹的张量流方式来做到这一点?我希望能够提取图像,例如image, label = sess.run(extract_image, feed_dict={path:filename})
    • 编辑了我的答案
    • 我得到:DecodeError: Error parsing message at 1, using this record: !wget -O "/tmp/train.tfrecords" "ciir.cs.umass.edu/downloads/Antique/tf-ranking/ELWC/…"
    猜你喜欢
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2017-06-30
    相关资源
    最近更新 更多