Tensorflow高效的每像素梯度计算

时间:2016-11-09 00:10:48

标签: python tensorflow deep-learning gradients

我使用tensorflow重新实现了论文Learning Image Matching by Simply Watching Video,并且在从网络抓取渐变时遇到了一些严重的性能问题。为了快速回顾他们在论文中所做的事情,他们拥有训练有素的网络,他们做了1个前向道具来获得插值图像,然后他们做了w * h / stride ^ 2 backprops来获得每个输入的输出的梯度。像素。由于反向传播的数量很多,这必须相当有效地完成,以便在合理的时间内获得梯度(在论文中,每个反向提升的时间为8分钟,150毫秒时间为128 * 384/16像素(步幅4)在行和列上))。由于在张量流中,由于梯度聚合而无法对多个反向支持进行批处理(例如参见this discussion),我需要执行以下操作:

for i in range(0, h, stride): 
    for j in range(0, w, stride):
        grad_output[0,i,j,:] = 1 #select current pixel
        grad.append(tf.gradients(predictions, images, grad_output))
        grad_output[grad_output != 0] = 0

获取每个像素的符号渐变,其中预测是网络的输出张量,图像是输入,声明为in gpu常量:

with tf.device('/gpu:0'):
    images = tf.constant(inp, dtype=tf.float32)

其中inp是包含数据的实际numpy数组。

每次对tf.gradients的调用大约需要0.35毫秒,这与作者在论文中的报告相比已经过多了。但是在评估符号渐变时花费的时间最多,如:

for i in range(0, len(grad)):
    res = sess.run(grad[i])

这需要大约1.5秒,非常慢。现在,对sess.run(grad[i])(具有相同索引i)的后续调用非常快,大约100毫秒,而在每次迭代运行for循环更改i导致每次迭代大约1.5秒。在看到这种行为后,我的猜测是将内容移到GPU上会有很大的开销,是否可能?如果是这种情况,我该如何避免呢?我已经将images张量移到GPU常量而不是使用占位符并依赖feed_dict中的sess.run,但这对性能没有任何明显的影响。任何加速评估符号渐变的想法?我觉得我在这里错过了一些简单的东西,因为1个反向启动需要1.5秒才真正远离任何现实场景(训练网络能够每秒处理大约100个样本,所以它不是架构问题我猜..)

谢谢!

1 个答案:

答案 0 :(得分:0)

以下是我的想法:

  1. 尝试将学习图表可视化,例如:通过tensorboardSummaryWriter。循环中的tf.gradients看起来很可疑 - 请确保您没有创建超过必要的张量。
  2. 如果它不改变您的语义,请尝试一次计算所有渐变:

    res = sess.run(grad)

  3. 假设grad是张量列表。在循环中执行sess.run会多次重新计算grad[i]grad[j]的常见副本。

    希望它有所帮助!