Python `tf.train.shuffle\u batch`在TensorFlow中读取`TFRecord`文件时崩溃

Python `tf.train.shuffle\u batch`在TensorFlow中读取`TFRecord`文件时崩溃,python,tensorflow,Python,Tensorflow,我正在尝试使用TensorFlow 1.0使用tf.train.shuffle\u batch来使用TFRecord文件中的成批数据。有关职能包括: def tfrecord_to_graph_ops(filenames_list): file_queue = tf.train.string_input_producer(filenames_list) reader = tf.TFRecordReader() _, tfrecord = reader.read(file_

我正在尝试使用TensorFlow 1.0使用
tf.train.shuffle\u batch
来使用
TFRecord
文件中的成批数据。有关职能包括:

def tfrecord_to_graph_ops(filenames_list):
    file_queue = tf.train.string_input_producer(filenames_list)
    reader = tf.TFRecordReader()
    _, tfrecord = reader.read(file_queue)

    tfrecord_features = tf.parse_single_example(
        tfrecord,
        features={'targets': tf.FixedLenFeature([], tf.string)}
    )
    ## if no reshaping: `ValueError: All shapes must be fully defined` in
    ## `tf.train.shuffle_batch`
    targets = tf.decode_raw(tfrecord_features['targets'], tf.uint8)
    ## if using `strided_slice`, always get the first record
    # targets = tf.cast(
    #     tf.strided_slice(targets, [0], [1]),
    #     tf.int32
    # )
    ## error on shapes being fully defined
    # targets = tf.reshape(targets, [])
    ## get us: Invalid argument: Shape mismatch in tuple component 0.
    ## Expected [1], got [1000]
    targets.set_shape([1])
    return targets


def batch_generator(filenames_list, batch_size=BATCH_SIZE):
    targets = tfrecord_to_graph_ops(filenames_list)
    targets_batch = tf.train.shuffle_batch(
        [targets],
        batch_size=batch_size,
        capacity=(20 * batch_size),
        min_after_dequeue=(2 * batch_size)
    )
    targets_batch = tf.one_hot(
        indices=targets_batch, depth=10, on_value=1, off_value=0
    )
    return targets_batch


def examine_batches(targets_batch):
    with tf.Session() as sess:
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(coord=coord)
        for _ in range(10):
            targets = sess.run([targets_batch])
            print(targets)
        coord.request_stop()
        coord.join(threads)
代码通过
inspect\u batches()
进入,并将
batch\u generator()
的输出交给了它
batch\u generator()
调用
tfrecord\u到\u graph\u ops()

我打电话来

targets = tf.decode_raw(tfrecord_features['targets'], tf.uint8)
在具有1000字节(数字0-9)的文件上。如果在会话中对此调用
eval()
,它将显示所有1000个元素。但如果我尝试将其放入批处理生成器中,它就会崩溃

如果我不重塑
目标
,我会得到一个类似
ValueError的错误:当调用
tf.train.shuffle\u batch
时,必须完全定义所有形状。如果我调用
targets.set_shape([1])
,让人想起谷歌的,我会得到一个类似
无效参数的错误:元组组件0中的形状不匹配。应为[1],在
tf.train.shuffle\u批中获得[1000]
。我还尝试使用
tf.stripped_slice
来剪切一大块原始数据-这不会崩溃,但只会导致一次又一次地获取第一个事件

正确的方法是什么?要从
TFRecord
文件中提取批次

请注意,我可以手动编写一个函数来切碎原始字节数据并进行某种批处理—如果我使用
feed_dict
方法将数据放入图形中,这尤其容易—但我正在尝试学习如何使用TensorFlow的
TFRecord
文件以及如何使用其内置批处理函数


谢谢

Allen Lavoie在评论中指出了正确的解决方案。重要的缺失部分是
enqueue\u many=True
作为
tf.train.shuffle\u batch()
的参数。编写这些函数的正确方法是:

def tfrecord_to_graph_ops(filenames_list):
    file_queue = tf.train.string_input_producer(filenames_list)
    reader = tf.TFRecordReader()
    _, tfrecord = reader.read(file_queue)

    tfrecord_features = tf.parse_single_example(
        tfrecord,
        features={'targets': tf.FixedLenFeature([], tf.string)}
    )
    targets = tf.decode_raw(tfrecord_features['targets'], tf.uint8)
    targets = tf.reshape(targets, [-1])
    return targets

def batch_generator(filenames_list, batch_size=BATCH_SIZE):
    targets = tfrecord_to_graph_ops(filenames_list)
    targets_batch = tf.train.shuffle_batch(
        [targets],
        batch_size=batch_size,
        capacity=(20 * batch_size),
        min_after_dequeue=(2 * batch_size),
        enqueue_many=True
    )
    return targets_batch

解码的字符串中总是有1000个元素吗?如果是这样,您可以将形状设置为1000而不是1。否则,填充是获得固定形状的常见解决方案。或者,如果要将这些字符单独添加到队列中,可以使用
enqueue\u many=True
shuffle\u batch
。不,数字会有所不同-这只是一个玩具问题<不过,code>enqueue\u many
是一个有趣的想法。
enqueue\u many=True
原来就是这个窍门!