我使用这里描述的方法来批量加载一些训练图像,基本上是这样的:
def read_my_file_format(filename_queue): # ... 使用读取器和解码器def input_pipeline(filenames, batch_size, num_epochs=None): filename_queue = tf.train.string_input_producer(...) example, label = read_my_file_format(filename_queue) example_batch, label_batch = tf.train.shuffle_batch( [example, label], batch_size=batch_size, ...) return example_batch, label_batchdef build_net(): batch, label = input_pipeline(...) y = encoder(batch) # <- 使用批次构建网络def train(): with tf.Session() as sess: # ... 初始化变量 coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) try: while not coord.should_stop(): # ... 训练步骤 except tf.errors.OutOfRangeError: print('训练完成 -- 达到周期限制') finally: coord.request_stop() coord.join(threads) sess.close()
这些对于训练来说都没问题——然而,我不明白如何测试生成的网络!让我困惑的是:
input_pipeline
返回的张量是网络的一部分。对于测试,我需要替换它吗?- 我在想是否可以为测试创建另一个
input_pipeline
,即使用不同的文件名队列。然后我可以使用tf.cond
在不同的输入批次之间切换,但这样的话:如何确保一次只耗尽一个队列?我不知道如何访问不同的队列以及如何指定它们是如何卸载的。
基本上,这个问题归结为:使用 tf.train.shuffle_batch
方法构建的网络的标准测试方法是什么?
回答:
你关于为数据集评估创建额外输入管道的想法绝对是正确的方向。使用多个输入管道是推荐的方法之一,这将包括两个过程——在一个上进行训练,在另一个上进行评估。在训练过程中使用检查点,然后每千步,代码可以尝试eval
模型,对训练和测试数据集进行评估。
引用自文档:
- 训练过程读取训练输入数据,并定期写入包含所有训练变量的检查点文件。
- 评估过程将检查点文件恢复到读取验证输入数据的推理模型中。
即使训练已经完成/退出后,也可以进行评估。(查看此示例)
另一个考虑是,通过共享变量,训练和评估可以在同一个图表中在同一个进程中运行,同时共享它们的训练变量!
关于你对队列耗尽的担忧,如果你将 tf.train.shuffle_batch*
的 num_threads 设置为大于1,它会同时从一个文件中读取(+比使用1个线程更快),而不是同时从N个文件中读取,(参见关于批处理的部分)。