2016-01-21 33 views
3

我有一些代码从张量记录中读取图像,对它们进行预处理(剪切,应用随机色调/饱和度等,全部通过张量自身的方法),然后使用shuffle_batch_join生成批次。如果在cpu上完成读取/预处理,Tensorflow网络会发散

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上时聚合网络。然而,这正是我的代码的瓶颈,我想通过把它放在CPU上,并将它放在with tf.device('/cpu:0'):中来加速它。有了这个,我有更快的迭代次数(大约1/5),但是网络在大约10次迭代之后发散,导致NaN损失。当目视检查张量板中产生的样品时,没有明显的差异。

为什么cpu vs gpu的收敛行为不同?我怎么能进一步调查这种奇怪的行为?

+1

这很奇怪。我的猜测是,GPU和其中一个图像处理操作的CPU实现存在一个错误(或不一致)。为了进行调查,我建议:(1)用'tf.Session(config = tf.ConfigProto(log_device_placement = True)')来构建会话,以查看工作版本中GPU实际调度哪些操作,然后有选择地将它们移动到CPU以查看哪一个可能导致此问题。 – mrry

+0

@ mrry好主意,我会做到这一点,并在github上找到问题后再开启一个问题。 – panmari

+2

你有没有设法本地化这个问题?我遇到了类似的问题(使用TF 0.8.0),其中我的管道在GPU上运行良好,但在CPU上,它开始频繁地生成NaN。 –

回答

0

我有一个非常类似的问题。在我的情况下,我将图像转换操作固定在GPU上,但数据是从CPU上的队列中馈入的。对我来说,把操作系统固定到GPU是一个错误,所以我用with tf.device('/cpu:0')将它们固定在CPU上,我的数值不稳定性问题就消失了。

值得注意的是,我以前也在GPU上运行过这些图像预处理步骤,但没有使用队列来加载数据。我只是通过占位符将数据直接提供给GPU,一切都运行良好。

它只是当我开始使用队列,并从独立的线程加载这些队列,我开始看到这个问题(当我没有从单独的线程加载它们时,我能够按顺序使用队列)。

我还没有确切的答案,但它似乎确保数据和图像预处理操作始终放置在相同的设备上是非常关键的。