在tensorflow中如何在多个输入数据文件中获得良好的混合效果

8
我正在使用tensorflow训练深度CNN来进行围棋的移动预测。我创建的数据集包括100,000个二进制数据文件,每个数据文件对应一场录制的比赛,并且包含大约200个训练样本(每个游戏中的一个移动)。我认为在使用SGD时,获得良好的混合非常重要。我希望我的批次包含来自不同游戏和不同阶段的样本。例如,仅从100个文件的开头读取一个样本并进行洗牌是不好的,因为这些100个样本都是每场比赛的第一步。
我已经阅读了有关从文件中提供数据的教程,但我不确定它们提供的库是否符合我的需求。如果我要自己编写代码,我基本上会初始化一堆指向每个文件内随机位置的文件指针,然后从随机文件中获取样本,相应地递增文件指针。
因此,我的问题是,Tensorflow是否提供这种功能,还是编写自己的代码来创建批次更容易?
2个回答

11

是的 - 你需要使用两种方法的组合。 (请注意,此答案适用于 TensorFlow v1,一些功能已被新的 tf.data 管道所取代;我已更新答案以指向 v1 兼容版本的内容,但如果您正在查找新代码,请参考tf.data。)

首先,通过使用带有 shuffle=Truetf.train.string_input_producer 随机打乱输入数据文件的顺序,并将其馈送到您使用的任何输入方法中(如果您可以将示例放入 tf.Example proto 格式,则可以轻松使用 parse_example)。非常清楚地说,您将文件名列表放入 string_input_producer 中,然后使用另一种方法(如 read_file 等)读取它们。

其次,您需要以更细的粒度进行混合。 您可以通过将输入示例馈送到具有大容量和大值min_after_dequeuetf.train.shuffle_batch节点中来实现此目的。 一种特别好的方法是使用shuffle_batch_join从多个文件接收输入,以便您获得很好的混合效果。 将批次的容量设置得足够大,以便在不耗尽RAM的情况下进行混合。 数万个示例通常效果很好。
请记住,批处理函数会向QUEUE_RUNNERS集合添加一个QueueRunner,因此您需要运行tf.train.start_queue_runners()

我这样理解是否正确:带有100%容量和shuffle=True的string_input_producer将产生完美混合,而无需进行批次洗牌? - TimZaman
链接已经失效。 - Dave
谢谢!我已经更新了答案,指向新的tf.data API,应该用于新代码;并且指向了答案中引用的函数的v1.compat版本的文档。感谢提醒。 - dga

0
在您的情况下,对于所有文件进行一些预处理并创建一个文件并不是问题。对于这种类型的游戏,历史记录并不重要,位置决定一切,因此您的数据集可以仅包含“位置->下一步”的内容。

对于更广泛的情况,TF提供了一切允许您想要的洗牌。有两种类型的洗牌,它们服务于不同的目的并洗牌不同的东西:

  • tf.train.string_input_producer shuffle: 布尔值。如果为真,则在每个epoch内随机洗牌字符串。。因此,如果您有几个文件['file1','file2',...,'filen'],则会从此列表中随机选择一个文件。如果为假,则文件一个接一个地跟随。
  • tf.train.shuffle_batch 通过随机洗牌张量创建批次。因此,它从您的队列中取出batch_size张量(您需要使用tf.train.start_queue_runners创建队列),然后将它们洗牌。

链接已经失效。 - Dave

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