尝试使用tf.Data解决培训/测试摘要

时间:2019-05-10 20:34:40

标签: python-3.x tensorflow tensorboard

我希望在我的NN培训期间开发摘要,类似于here,但是我看到的所有示例都使用feed_dict而不是tf.data。我的培训和测试有单独的初始化程序:

self.train_init = iterator.make_initializer(train_data) # initializer for train_data
self.test_init = iterator.make_initializer(test_data)   # initializer for test_data

在训练期间,我使用sess.run(self.train_init)初始化训练初始化程序,但是为了测试准确性,我相信我需要初始化sess.run(self.test_init)。目前,我的代码如下所示:

for i in range(100):
    sess.run(self.train_init)
    total_loss = 0
    n_batches = 0
    try:
        while True:
              _, l = sess.run([self.optimizer, self.loss])
              total_loss += l
              n_batches += 1
    except tf.errors.OutOfRangeError:
        pass

        if i % (10/1) == 0:
           print('Avg. loss epoch {0}: {1}'.format(i, total_loss/n_batches))
           acc, summ = sess.run(self.accuracy, self.summary_op)
           writer.add_summary(summ, i)

按照目前的情况,每10次迭代就测量一次精度,但是精度是使用训练批次而不是测试批次来测量的。我希望能够随着时间的推移查看训练和测试的准确性,以便清楚地查看是否发生过度拟合(训练准确性高但测试准确性差)。

我不知道在使用tf.Data时如何执行此操作。在进行100次迭代时,如何在初始化程序之间切换,同时始终创建所需的摘要?

1 个答案:

答案 0 :(得分:3)

通常,人们会在训练过程之外评估测试集,以优化性能。但是,如果您真的想在原地完成该任务,对我来说最有效的解决方案之一就是:

  1. 创建两个tf.data,并使用一个占位符在它们之间进行切换。
  2. 使用tf.cond()控制流,如this post

代码可能类似于:

with tf.name_scope('train_pipeline'):
    train_ds = tf.data.Dataset.from_tensor_slices(...)
    ...
    train_ds = iterator.make_initializer(train_data)
    train_init = iterator.initialize
    X_iterator_train = iterator.get_next()
with tf.name_scope('test_pipeline'):
    test_ds = tf.data.Dataset.from_tensor_slices(...)
    ...
    test_ds = iterator.make_initializer(test_data)
    test_init = iterator.initialize
    X_iterator_test = iterator.get_next()

train_or_test = tf.placeholder(tf.string, name='switch_buton')
def f1(): X_iterator_train
def f2(): X_iterator_test
inputs = tf.cond(tf.equal(train_or_test, 'train'), lambda :f1(), lambda: f2(), name='input_cond')

# model
... # use your input(IteratorGetNext) at your first layer, something like tf.nn.conv2d(inputs, ...)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    # init summary writers for two different path
    train_writer = tf.summary.FileWriter(...)
    test_writer = tf.summary.FileWriter(...)

    for ep in range(nb_epoch):
        sess.run([train_init, test_init])
        # begin training
        for step in range(nb_batch):
            # 90% train, 10% test
            if step % 9 == 0:
                sess.run(train_op, feed_dict={train_or_test: 'test'})  # switch to test input pipeline
                train_writer.add_summary()
            else:
                sess.run(train_op, feed_dict={train_or_test: 'train'})  # switch to train input pipeline
                test_writer.add_summary()