我有一些代码从张量记录中读取图像,对它们进行预处理(裁剪,应用随机色调/饱和度等,所有这些都通过张量流自己的方法),然后使用shuffle_batch_join
生成批次。
with tf.variable_scope('dump_reader'):
all_files = glob.glob(dump_file + '*')
filename_queue = tf.train.string_input_producer(all_files, num_epochs=epochs)
example_list = [read_tensor_record(filename_queue, image_size)
for _ in range(read_threads)]
return tf.train.shuffle_batch_join(example_list, batch_size=batch_size,
capacity=min_queue_size + batch_size * 16,
min_after_dequeue=min_queue_size)
这很有效,并且在将所有操作放在gpu上时会导致融合网络。但是,现在这是我的代码的瓶颈,我想通过将此块包装在with tf.device('/cpu:0'):
中来将其放在cpu上来加快速度。有了这个,我有更快的迭代(大约1/5),但网络在大约10次迭代后发散,导致NaN的损失。当目视检查在张量板中产生的样品时,没有明显的差异。
为什么cpu vs gpu的收敛行为不同?我怎么能进一步调查这种奇怪的行为?
答案 0 :(得分:0)
我遇到了一个非常类似的问题。在我的情况下,我已将图像转换操作固定到GPU,但数据是从CPU上的队列中提供的。对我来说,将操作固定到GPU是错误的,所以我用with tf.device('/cpu:0')
将它们固定到CPU上,我的数值不稳定性问题就消失了。
值得注意的是,我之前在GPU上运行过这些图像预处理步骤,但没有使用队列来加载数据。我只需通过占位符将数据直接提供给GPU,一切运行正常。
只有当我开始使用队列,并从独立线程加载这些队列时才开始看到这个问题(当我没有从不同的线程加载队列时,我能够以顺序方式使用队列)。
对于发生的事情,我没有确切的答案,但似乎确保数据和图像预处理操作始终放在同一设备上非常关键。