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

3

你好,我正在尝试构建一个图像输入管道。我的预处理训练数据存储在一个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]))

..

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())

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

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

很遗憾,这个不起作用。我收到了以下错误消息:
ValueError: Tensor conversion requested dtype string for Tensor with dtype int64: 'Tensor("ParseSingleExample/Squeeze_label:0", shape=(), dtype=int64)' ... TypeError: Input 'bytes' of 'DecodeRaw' Op has type int64 that does not match expected type of string.
有人能给我一些修复的提示吗?
提前感谢!
更新:read_and_decode的完整代码清单
@mmry非常感谢您。现在我的代码在批次混洗时中断。具体如下:
ValueError: All shapes must be fully defined: [TensorShape([Dimension(None), Dimension(None), Dimension(None)]), TensorShape([])]
有什么建议吗?

你好,你已经在你的tfrecords中序列化了label_text。那么你如何在解码器中解析这些数据呢?能否给一些建议?谢谢。 - mining
record_iterator = tf.python_io.tf_record_iterator(path=<FILE_NAME>)对于每个string_record in record_iterator: example = tf.train.Example() example.ParseFromString(string_record)label_txt = (example.features.feature['label_text'].bytes_list .value[0].decode("utf-8")) - monchi
以上示例将遍历所有数据元素并解码标签字符串。 - monchi
非常感谢您的评论! - mining
1个回答

6

在这行代码中,不需要使用tf.decode_raw()操作:

label = tf.decode_raw(features['label'], tf.int64)

相反,你应该能够编写:

label = features['label']

tf.decode_raw()操作仅接受 tf.string 张量,并将某些张量数据的二进制表示(作为可变长度字符串)转换为类型化表示(作为特定类型元素的向量)。但是,您已经将特征'label'定义为具有 tf.int64 类型,因此如果要将其用作 tf.int64 ,则无需转换该特征。


2
我认为这里的问题在于每个图像的大小都可能不同(根据 'height''width''depth' 特征)。要使用 tf.train.shuffle_batch(),您必须调整图像的大小,使它们都具有相同的大小,例如使用像 tf.image.resize_image_with_crop_or_pad() 这样的图像处理操作。如果输入中的所有图像都具有相同的大小,则可以将该大小作为常量(例如 [299, 299, 3])传递给 tf.reshape(),然后 tf.train.shuffle_batch() 将正常工作。 - mrry
1
太好了!所有的图像都有相同的大小,所以我传递了一个固定的数字!我最初在训练集中包含了尺寸,这样如果需要重构图片就可以使用。 - monchi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接