读写 tfrecords 二进制文件(类型不匹配)

mon*_*chi 3 binary image-processing tensorflow

嗨,我正在尝试构建一个图像输入管道。我的预处理训练数据存储在我使用以下代码行创建的 tfrecords 文件中:

def _bytes_feature(value):
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

def _int64_feature(value):
    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
Run Code Online (Sandbox Code Playgroud)

..

img_raw = img.tostring()                                        # typeof(img) = np.Array with shape (50, 80) dtype float64
img_label_text_raw = str.encode(img_lable)
example = tf.train.Example(features=tf.train.Features(feature={
    'height': _int64_feature(height),                           #heigth (integer)
    'width': _int64_feature(width),                             #width (integer)
    'depth': _int64_feature(depth),                             #num of rgb channels (integer)
    'image_data': _bytes_feature(img_raw),                      #raw image data (byte string)
    'label_text': _bytes_feature(img_label_text_raw),           #raw image_lable_text (byte string)
    'lable': _int64_feature(lable_txt_to_int[img_lable])}))     #label index (integer)

writer.write(example.SerializeToString())
Run Code Online (Sandbox Code Playgroud)

现在我尝试读取二进制数据以从中重建张量:

def read_and_decode(filename_queue):
    reader = tf.TFRecordReader()
    _, serialized_example = reader.read(filename_queue)

    features = tf.parse_single_example(
        serialized_example,
        # Defaults are not specified since both keys are required.
        features={
            'label': tf.FixedLenFeature([], tf.int64),
            'height': tf.FixedLenFeature([], tf.int64),
            'width': tf.FixedLenFeature([], tf.int64),
            'depth': tf.FixedLenFeature([], tf.int64),
            'image_data': tf.FixedLenFeature([], tf.string)
        })

    label = features['label']
    height = tf.cast(features['height'], tf.int64)
    width = tf.cast(features['width'], tf.int64)
    depth = tf.cast(features['depth'], tf.int64)

    image_shape = tf.pack([height, width, depth])
    image = tf.decode_raw(features['image_data'], tf.float64)
    image = tf.reshape(image, image_shape)


    images, labels = tf.train.shuffle_batch([image, label],     batch_size=2,
                                                 capacity=30,
                                                 num_threads=1,
                                                 min_after_dequeue=10)
    return images, labels
Run Code Online (Sandbox Code Playgroud)

可悲的是,这不起作用。我收到此错误消息:

ValueError: Tensor 转换为 dtype int64 的 Tensor 请求 dtype 字符串:'Tensor("ParseSingleExample/Squeeze_label:0", shape=(), dtype=int64)' ...

类型错误:“DecodeRaw”操作的输入“字节”的类型为 int64,与预期的字符串类型不匹配。

有人可以给我一个关于如何解决这个问题的提示吗?

提前致谢!

更新:“read_and_decode”的完整代码清单

@mmry 非常感谢。现在我的代码在洗牌时中断。和:

ValueError:必须完全定义所有形状:[TensorShape([Dimension(None), Dimension(None), Dimension(None)]), TensorShape([])]

有什么建议?

mrr*_*rry 5

无需tf.decode_raw()在此行中使用操作:

label = tf.decode_raw(features['label'], tf.int64)
Run Code Online (Sandbox Code Playgroud)

相反,您应该能够编写:

label = features['label']
Run Code Online (Sandbox Code Playgroud)

tf.decode_raw()运算只接受tf.string张量,并转换一些张量数据的二进制表示(作为可变长度的字符串)转换成类型化表示(如特定类型的元件的载体)。但是,您已将该功能定义'label'为具有 type tf.int64,因此如果要将其用作tf.int64.

  • 我认为这里的问题是您的每个图像都可以是不同的大小(根据“高度”、“宽度”和“深度”功能)。要使用`tf.train.shuffle_batch()`,您必须调整图像的大小,使它们都具有完全相同的大小,例如使用像 [`tf.image.resize_image_with_crop_or_pad()`](https:/ /www.tensorflow.org/api_docs/python/image/cropping#resize_image_with_crop_or_pad)。如果输入 *do* 中的所有图像都具有相同的大小,您可以将该大小作为常量(例如`[299, 299, 3]`)传递给 `tf.reshape()` 和 `tf.train。 shuffle_batch()` 会起作用。 (2认同)