我正在使用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 回答
以下是我的想法:
尝试可视化学习图,例如通过tensorboard和SummaryWriter . 循环中的
tf.gradients
看起来很可疑 - 请确保您没有创建超过必要的张量 .如果它不改变您的语义,请尝试一次计算所有渐变:
res = sess.run(grad)
假设
grad
是张量列表 . 在循环中执行sess.run
将多次重新计算grad[i]
和grad[j]
的任何常见项 .希望能帮助到你!