2016-11-09 49 views
2

我正在使用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個樣本,所以這不是一個架構問題,我猜...)

謝謝!

回答

0

這裏是我的想法:

  1. 嘗試以可視化的學習曲線,例如通過tensorboardSummaryWritertf.gradients在循環中看起來很可疑 - 請確保您不會創建超過必要的張數。
  2. 如果它不會改變你的語義,嘗試一次計算所有梯度:

    解析度= sess.run(畢業)

假設grad是張量的列表。在循環中執行sess.run將重新計算多次grad[i]grad[j]的任何常見父母。

希望它有幫助!