我正在使用TF使用图像训练GAN。到目前为止,我已经建立了模型,并且只使用了我的训练集(由tfrecord文件构建)和一个参考批处理来进行张量板可视化,并且在Titan V上获得了不错的恒定性能(0.38〜0.40s /批)当我使用可初始化的迭代器并在训练数据集和可视化样本之间进行切换(在每个训练时期之后)。
由于一切正常,我必须在每个训练步骤之后添加一个测试集和一个测试步骤。 由于两个数据集中的样本数量不同,因此我决定使用可迭代的迭代器在三个数据集之间进行切换,因为我需要在每次迭代中绘制两个损耗(我的global_step是一个迭代,而不是一个时期)我需要在切换数据集后恢复迭代。
实施此操作后,我的演奏急剧下降并变得不稳定。现在,每个训练步骤需要0.35到1.95 s之间的时间,但是每16、32或42次迭代都会冻结任意几秒钟(30+)。问题在于它不是在固定指令上发生,而是经常在相同数量的迭代之后发生)。
这是我用来构建数据集管道的函数:
def load_dataset(name, batch_size=32, prefetch_buffer=1, interleave=1, n_threads=os.cpu_count())
# parse sample is a lambda (omitted)
parsed_dataset = dataset.map(parse_sample, num_parallel_calls=n_threads)
# Here there's a series of filter() that I omitted
parsed_dataset = parsed_dataset.cache()
parsed_dataset = parsed_dataset.shuffle(shuffle_buffer, reshuffle_each_iteration=True)
parsed_dataset = parsed_dataset.repeat()
parsed_dataset = parsed_dataset.batch(batch_size)
if interleave > 1:
parsed_dataset = parsed_dataset.interleave(lambda x: tf.data.Dataset.from_tensors(x).repeat(interleave), cycle_length=n_threads, block_length=interleave, num_parallel_calls=n_threads)
parsed_dataset = parsed_dataset.prefetch(prefetch_buffer)
return parsed_dataset
我需要交织以使训练数据集在后续调用中返回3个相同的批次。
我没有更改数据集管道中的任何内容,但仍然为prefetch_buffer,shuffle_buffer和n_threads尝试了许多不同的值。还尝试删除repeat()
或cache()
,两者之间没有实质性差异。我唯一的区别是长时间冻结的频率,但无法确定与哪个参数有关。
我使用可迭代的迭代器的训练循环是:
train_dataset = dh.load_dataset('train',prefetch_buffer=1,shuffle_buffer=32,interleave=3)
validation_dataset = dh.load_dataset('valid',prefetch_buffer=1,shuffle_buffer=32)
tensorboard_datasets = dh.load_dataset('tboard', prefetch_buffer=1, shuffle_buffer=1)
use_dataset=tf.placeholder(tf.string, shape=[])
iterator = tf.data.Iterator.from_string_handle(use_dataset, train_dataset.output_types, train_dataset.output_shapes)
next_batch = iterator.get_next()
train_iterator = train_dataset.make_initializable_iterator()
valid_iterator = validation_dataset.make_initializable_iterator()
tboard_iterator = tensorboard_datasets.make_initializable_iterator()
# Initializers for the datasets
reset_train_iter = train_iterator.initializer
reset_validation_iter = valid_iterator.initializer
reset_tboard_iter = tboard_iterator.initializer
with tf.Session() as sess:
# Handles to switch between datasets
use_train_dataset = sess.run(train_iterator.string_handle())
use_valid_dataset = sess.run(valid_iterator.string_handle())
use_tboard_dataset = sess.run(tboard_iterator.string_handle())
while self.layers['train']['global_step'] <= self.params['max_iterations']:
# Initialize iterators
sess.run([reset_train_iter, reset_validation_iter, reset_tboard_iter])
print("Training...")
for i in range(self.params['save_every_itn']):
# Training of C and S
_ = sess.run(self.layers['train']['step_C'], feed_dict={use_dataset: use_train_dataset, is_training: True})
_ = sess.run(self.layers['train']['step_S'], feed_dict={use_dataset: use_train_dataset, is_training: True})
# Visualizing losses for each iteration
self.visualizer.log(sess, show='train_loss', feed_dict={use_dataset: use_train_dataset, is_training: True})
self.visualizer.log(sess, show='test_loss', feed_dict={use_dataset: use_valid_dataset, is_training: False})
self.layers['train']['global_step'] += 1
print("Checkpoint...")
self.save(sess)
# Show a prediction made with a reference sample:
# Show the differences by using trained and current BatchNorm weights.
self.visualizer.log(sess, show='train', feed_dict={use_dataset: use_tboard_dataset, is_training: True})
self.visualizer.log(sess, show='test', feed_dict={use_dataset: use_tboard_dataset, is_training: False})
其中“ visualizer”是一类,我保留用于管理Tensorboard的所有代码。它只是运行正确的摘要('*_loss'
是一个操作,仅记录训练和测试损失,而其他两个也打印图像和其他内容)。问题不应该存在,因为我尝试删除了调用,但是迭代器的问题仍然存在。
如果重要的话,培训和验证数据集实际上是应用于同一.tfrecords文件的不同过滤器。
我不知道为什么计算如此不稳定,它在夜间进行了14k次迭代,而以前的版本却进行了约90k次迭代。 top表示,Python进程在处理数据时会占用我们Xeon E5-2609的200%-300%和64GB RAM中的22个。
有人在这种迭代器上有经验吗?