機器學習演算法的除錯 —— 梯度檢驗(Gradient Checking)
阿新 • • 發佈:2019-01-11
反向傳播演算法很難除錯得到正確結果,尤其是當實現程式存在很多難於發現的bug 時。舉例來說,索引的缺位錯誤(off-by-one error)會導致只有部分層的權重得到訓練(for(i=1; i<=m; ++i)
被漏寫為 for(i=1; i<m; ++i)
),再比如忘記計算偏置項。這些錯誤會使你得到一個看似十分合理的結果(但實際上比正確程式碼的結果要差)。因此,僅從計算結果上來看,我們很難發現程式碼中有什麼東西遺漏了。本節中,我們將介紹一種對求導結果進行數值檢驗的方法,該方法可以驗證求導程式碼是否正確。另外,使用本節所述求導檢驗方法,可以幫助你提升寫正確程式碼的信心。
數學原理
考慮我們想要最小化以
我們不妨以 Sigmoid 函式為例,也即
回憶導數的數學定義:
由此我們可得梯度校驗的數值校驗公式:
這便是梯度檢驗的原理。在實際應用中,我們常將
程式設計實現
import numpy as np
def sigmoid(z):
return 1./(1+np.exp(-z))
def sigmoid_prime(z):
return sigmoid(z)*(1 -sigmoid(z))
def check_gradient(f, x0, epsilon):
return (f(x0+epsilon) - f(x0-epsilon))/2/epsilon
if __name__ == '__main__':
x0 = np.array([1, 2, 3])
epsilon = 1e-4
print(sigmoid_prime(x0))
# [ 0.19661193 0.10499359 0.04517666]
print(check_gradient(sigmoid, x0, epsilon))
# [ 0.19661193 0.10499359 0.04517666]