Tensorflow 如何从内存有限但数据集较大的TFR记录中获取无序批处理?

Tensorflow 如何从内存有限但数据集较大的TFR记录中获取无序批处理?,tensorflow,shuffle,Tensorflow,Shuffle,使用tensorflow函数tf.train.shuffle\u batch我们通过将tfrecord作为一个队列读入内存并在队列中进行无序处理(嗯,如果我理解正确的话)。现在我有了一个高度有序的tfrecords(相同标签的图片被写在一起)和一个非常大的数据集(大约2550000张图片)。我想给我的Vgg网络添加一批随机标签,但将所有图片读入内存并洗牌是不可能的,也是丑陋的。有什么解决办法吗 我想可能先做洗牌,然后把它们写进TFrecord,但我想不出一个有效的方法来做到这一点 我的数据以以下

使用tensorflow函数tf.train.shuffle\u batch我们通过将tfrecord作为一个队列读入内存并在队列中进行无序处理(嗯,如果我理解正确的话)。现在我有了一个高度有序的tfrecords(相同标签的图片被写在一起)和一个非常大的数据集(大约2550000张图片)。我想给我的Vgg网络添加一批随机标签,但将所有图片读入内存并洗牌是不可能的,也是丑陋的。有什么解决办法吗

我想可能先做洗牌,然后把它们写进TFrecord,但我想不出一个有效的方法来做到这一点

我的数据以以下方式保存:

以下是获取TFR记录的代码:

dst = "/Users/cory/Desktop/3_key_frame"

classes=[]
for myclass in os.listdir(dst):
    if myclass.find('.DS_Store')==-1:
        classes.append(myclass)


writer = tf.python_io.TFRecordWriter("train.tfrecords")
for index, name in enumerate(classes):
    class_path = dst +'/' + name
    #print(class_path)
    for img_seq in os.listdir(class_path):
        if img_seq.find('DS_Store')==-1:
            seq_pos = class_path +'/' + img_seq
            if os.path.isdir(seq_pos):
                for img_name in os.listdir(seq_pos):
                    img_path = seq_pos +'/' + img_name
                    img = Image.open(img_path)
                    img = img.resize((64,64))
                    img_raw = img.tobytes()
                    #print (img,index)
                    example = tf.train.Example(features=tf.train.Features(feature={
                        "label":tf.train.Feature(int64_list=tf.train.Int64List(value=[index])),
                        'img_raw':tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
                        }))
                    writer.write(example.SerializeToString())
writer.close()

假设您的数据存储方式如下:

/path/to/images/LABEL_1/image001.jpg
/path/to/images/LABEL_1/image002.jpg
...
/path/to/images/LABEL_10/image001.jpg
将所有文件名放在一个简单的列表中,并将其洗牌:

import glob
import random
filenames = glob.glob('/path/to/images/**/*.jpg)
random.shuffle(filenames)
创建从标签名称到数字标签的字典:

class_to_index = {'LABEL_1':0, 'LABEL_2': 1} # more classes I assume...
现在,您可以在所有图像上循环并检索标签

writer = tf.python_io.TFRecordWriter("train.tfrecords")
for f in filenames:
    img = Image.open(f)
    img = img.resize((64,64))
    img_raw = img.tobytes()
    label = f.split('/')[-2]
    example = tf.train.Example(features=tf.train.Features(feature={
                    "label":tf.train.Feature(int64_list=tf.train.Int64List(value= class_to_index[label])),
                    'img_raw':tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
                    }))
                writer.write(example.SerializeToString())
writer.close()

希望这有帮助:)

我想您已经知道了文件名列表和/或标记数据集的结构。 在一个类一个类的基础上遍历它们可能是值得的,每次取N个数量。本质上是交错数据集,这样就不会出现顺序问题。 如果我理解正确,您主要关心的是从TFRecord中采样数据集时,数据的子集可能完全包含一个类,而不是一个好的表示

如果您将其结构为:

0 0 0 0 1 1 1 1 2 2 2 2 0 0 0 0 1 1 1 1 2 2 2 2 ... etc
这可能会使“洗牌”批次更有可能创建更好的训练样本

这就是我所遵循的解决方案,因为似乎没有用于洗牌的额外参数,您可以指定这些参数来保持类标签在集合中的均匀分布