首页 文章

Tensorflow高效的每像素梯度计算

提问于
浏览
2

我正在使用tensorflow重新实现论文Learning Image Matching by Simply Watching Video,当我从网络中抓取渐变时,我面临着一些严重的性能问题 . 为了快速回顾他们在论文中所做的事情,他们拥有训练有素的网络,他们做了1个前向道具以获得插值图像,然后他们做了w * h / stride ^ 2反向推进以获得每个输入的输出的梯度像素 . 由于反向传播的数量很多,这必须相当有效地完成,以便在合理的时间内获得梯度(在论文中,每个反向提升的时间为8分钟,150毫秒时间为128 * 384/16像素(步幅为4)在行和列上)) . 由于在tensorflow中,由于梯度聚合而无法对多个backprop进行批处理(例如参见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 中的 feed_dict ,但是这并没有丢失一些简单的东西,因为1 backprop需要1.5秒,这远非任何现实场景(训练网络)例如,每秒能够处理大约100个样本,因此我认为这不是架构问题..)

谢谢!

1 回答

  • 0

    以下是我的想法:

    • 尝试可视化学习图,例如通过tensorboardSummaryWriter . 循环中的 tf.gradients 看起来很可疑 - 请确保您没有创建超过必要的张量 .

    • 如果它不改变您的语义,请尝试一次计算所有渐变:

    res = sess.run(grad)

    假设 grad 是张量列表 . 在循环中执行 sess.run 将多次重新计算 grad[i]grad[j] 的任何常见项 .

    希望能帮助到你!

相关问题