大小不等的Tensorflow TFR记录文件

大小不等的Tensorflow TFR记录文件,tensorflow,deep-learning,tensorflow-datasets,Tensorflow,Deep Learning,Tensorflow Datasets,目前,我将数据拆分为几个TFrecord文件,然后通过无序排列和交错方式读取数据。我的代码如下: path_to_files = glob('train_*.tfrecord') n_files = len(path_to_files) tf_dataset = tf.data.Dataset.list_files(path).shuffle(n_files) tf_dataset = tf_dataset.interleave(lambda filename: tf.data.TFRecord

目前,我将数据拆分为几个TFrecord文件,然后通过无序排列和交错方式读取数据。我的代码如下:

path_to_files = glob('train_*.tfrecord')
n_files = len(path_to_files)
tf_dataset = tf.data.Dataset.list_files(path).shuffle(n_files)
tf_dataset = tf_dataset.interleave(lambda filename: tf.data.TFRecordDataset(filename, num_parallel_reads=4).map(parseFunc), cycle_length=n_files)
tf_dataset = tf_dataset.shuffle(buffer_size=n_files*3)  
tf_dataset = tf_dataset.batch(batchsize)
tf_dataset = tf_dataset.prefetch(buffer_size=batchsize)
我有两个问题:

1) 我的老板正在做我想做的事。也就是说,它是否从每个TFrecord文件中平均随机抽样

2) 如果TFrecord文件包含非常不同数量的样本(例如,1将有50个样本,另500个样本),会发生什么情况。这会影响随机性吗


谢谢

Q1:不完全是。首先,这一行不需要显式洗牌,
list\u files
已经有了这个参数。它可以由种子值控制

tf_dataset = tf.data.Dataset.list_files(path, shuffle=True, seed=1).
如果没有repeat函数,当迭代器耗尽所有文件时,将出现序列结束错误。所以应该是这样。当
None
作为值传递时,它将无限期地迭代,或者您可以设置确切的纪元数

tf_dataset = tf.data.Dataset.list_files(path, shuffle=True, seed).repeat()
问题2:如果文件大小不同,也可以。唯一的结果是,大文件的内容被迭代器选择的几率更高。但这不会影响随机性。这一行将完成它的工作,洗牌交错的数据集。唯一需要记住的是,洗牌缓冲区控制加载到内存中的数据量。通常建议将其设置为dataset中的示例数(所有文件中的所有示例数),但在某些情况下,这可能会导致大量开销,甚至导致OOM

tf_dataset = tf_dataset.shuffle(buffer_size=n_files*3)  

因此,我运行了一个模拟来测试这一点,如下所示:我使用以下命令保存了3个文件: 文件1:~1000个1号样本 文件2:~2000个2号样本 文件3:~3000个3号样本

然后,我用上面的代码加载迭代器,并对批进行采样,直到迭代器用完。下面是我的结果

从图中可以看出,当TF从TFrecord文件中随机采样时,它不会根据其大小来衡量这些文件。相反,它以相同的概率从每个大小不等的文件中随机采样,直到其中一个文件的样本用完为止。然后,它以相同的概率从剩余的每个文件继续


带回家:要进行真正的随机抽样,请确保您的TFrecord文件大小相同,或者标签均匀分布在它们之间

路径到文件中有多少文件
?你试过你的密码吗?@Sharky我有6个文件。我已经运行了代码,它可以正常工作并生成随机批处理,但是由于文件非常大,我没有对其进行彻底测试。我希望这里有人能马上知道,不用parse func就可以试试。它将只输出文件名,并最终返回超出范围的错误,因为您的代码中没有重复。这只是因为您在
list\u文件中未使用shuffle。只要用一个文件和一个示例来尝试我的代码,第二个文件和10个示例就可以了。你会发现,这正是我想要的described@Sharky我尝试使用你的代码(
tf.data.Dataset.list_文件(path,shuffle=True,seed=1)
),得到了完全相同的结果。这确实很奇怪,因为你的代码给了我超出范围的错误