如何通過梯度檢驗幫助實現反向傳播
選自imaddabbura
機器之心編譯
參與:劉天賜、路
本文介紹了如何使用梯度檢驗方法確認反向傳播代碼是否準確。
在《Coding Neural Network - Forward Propagation and Backpropagation》一文中,我們藉助 numpy 實現了前向傳播和反向傳播演算法。但從頭開始實現反向傳播很容易遇到 bug 或者報錯。因此,在訓練數據上運行神經網路之前,必須檢驗反向傳播的實現是否正確。不過首先,我們先複習一下反向傳播的概念:從最後的節點開始,沿著拓撲排序的反方向遍歷所有節點,計算每個邊的尾節點相對於損失函數的導數。換言之,計算損失函數對所有參數的導數:?J/?θ,其中θ表示模型中的參數。
我們通過計算數值梯度並比較數值梯度和根據反向傳播求出的梯度(解析梯度)間的差異,來測試我們的實現代碼。這裡有兩種數值梯度的計算方法:
右邊形式:
(1) [J(θ+?)?J(θ)]/?
雙邊形式(見圖 2):
(2) [J(θ+?)?J(θ??)]/2?
圖 2:雙邊數值梯度
逼近導數的雙邊形式比右邊形式更接近真實值。我們以 f(x)=x^2 為例,在 x=3 處計算導數。
可以看到,解析梯度和雙邊數值梯度之間的差值幾乎為零;而和右邊形式的數值梯度之間的差值為 0.01。因此在下文中,我們使用雙邊形式計算數值梯度。
另外,我們使用下式對數值梯度和解析梯度間的差值進行標準化。
(3)
如果差值≤10^?7,可以認為反向傳播的實現代碼沒有問題;否則,就需要回去檢查代碼,因為一定有什麼地方出錯了。
以下是完成梯度檢驗的步驟:
1. 隨機從訓練集中抽取一些樣本,用來計算數值梯度和解析梯度(不要使用所有訓練樣本,因為梯度檢驗運行會很慢)。
2. 初始化參數。
3. 計算前向傳播和交叉熵損失。
4. 利用寫好的反向傳播的實現代碼計算梯度(解析梯度)。
5. 計算雙邊形式的數值梯度。
6. 計算數值梯度和解析解梯度的差值。
這裡,我們使用《Coding Neural Network - Forward Propagation and Backpropagation》中所寫的函數來實現參數初始化、前向傳播、反向傳播以及交叉熵損失的計算。
導入數據。
編寫 helper 函數,幫助實現參數和梯度詞典(gradients dictionary)到向量的相互轉換。
最後,編寫梯度檢驗函數,利用此函數計算解析梯度和數值梯度之間的差值,並藉此判斷反向傳播的實現代碼是否正確。我們隨機抽取 1 個樣本來計算差值:
結論
以下是一些關鍵點:
雙邊形式的數值梯度在逼近解析梯度時效果比單邊形式的數值梯度更好。
由於梯度檢驗的運行很慢,因此:
進行梯度檢驗時,只使用一個或少數樣本;
在確認反向傳播的實現代碼無誤後,訓練神經網路時記得取消梯度檢驗函數的調用。
如果使用了 drop-out 策略,(直接進行)梯度檢驗會失效。可以在進行梯度檢驗時,將 keep-prob 設置為 1,訓練神經網路時,再進行修改。
通常採用 e=10e-7 作為檢查解析梯度和數值梯度間差值的基準。如果差值小於 10e-7,則反向傳播的實現代碼沒有問題。
幸運的是,在諸如 TensorFlow、PyTorch 等深度學習框架中,我們幾乎不需要自己實現反向傳播,因為這些框架已經幫我們計算好梯度了;但是,在成為一個深度學習工作者之前,動手實現這些演算法是很好的練習,可以幫助我們理解其中的原理。
本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。
------------------------------------------------


※學習了!谷歌今日上線基於TensorFlow的機器學習速成課程,良心又免費
※BAIR提出MC-GAN,使用GAN實現字體風格遷移
TAG:機器之心 |