我正在使用tensorflow重新實現紙張Learning Image Matching by Simply Watching Video,並且在從網絡抓取梯度時遇到了一些嚴重的性能問題。爲了快速回顧他們在論文中做了什麼,他們有訓練有素的網絡,他們做前向支撐以獲得內插圖像,然後他們做w * h/stride^2反向傳播以獲得輸出的梯度以及每個輸入的梯度像素。由於反向傳播的次數很多,爲了在合理的時間內獲得梯度,必須進行相當高效的處理(在本文中,8分鐘內,每個反向傳播時間爲150ms,時間爲128 * 384/16像素(步幅4在行和列上))。由於tensorflow多backprops不能進行批處理,由於梯度聚集(參見例如this discussion),我需要做的是這樣的:Tensorflow高效的每像素梯度計算
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
以獲得每個像素,其中預測是的輸出張象徵梯度網絡和圖像是以gpu常量聲明的輸入:
with tf.device('/gpu:0'):
images = tf.constant(inp, dtype=tf.float32)
其中inp是包含數據的實際numpy數組。
每個打到tf.gradients
的電話都需要大約0.35 ms,這與作者在報告中報告的數字相比已經太多了。但最大的時間花在評估象徵性漸變上,如:
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
,但這對性能沒有任何明顯影響。任何想法來加速符號梯度的評估?我覺得我錯過了一些簡單的東西,因爲1秒的背投1.5秒與真實場景相距甚遠(例如訓練網絡每秒能夠處理大約100個樣本,所以這不是一個架構問題,我猜...)
謝謝!