? ? ? ? 在神經網絡訓練中,計算參數的梯度是關鍵步驟。numerical_gradient 方法旨在通過數值微分(中心差分法)計算損失函數對網絡參數的梯度。然而,該方法的實現存在一個關鍵問題,導致梯度計算錯誤。
1、錯誤代碼示例:
def numerical_gradient(self, x, t):loss_W = lambda W: self.loss(x, t) # 定義損失函數grads = {} # 存儲梯度結果# 計算各參數的梯度grads['W1'] = numerical_gradient(loss_W, self.params['W1'])grads['b1'] = numerical_gradient(loss_W, self.params['b1'])grads['W2'] = numerical_gradient(loss_W, self.params['W2'])grads['b2'] = numerical_gradient(loss_W, self.params['b2'])return grads
1、1關鍵問題:
1、2相關疑問及解答
在梯度下降中,為什么需要對以前的權重系數進行保存,并且用更新后的數據進行梯度下降?
回答:
1. 數值梯度計算中的權重保存
在 數值微分(Numerical Gradient) 過程中,需要臨時保存權重,以確保梯度計算的準確性。
場景:通過中心差分法計算梯度時,需對參數的每個分量進行微小擾動(如±ε),觀察損失的變化。
原因:
避免污染參數狀態:計算梯度時,需臨時修改某個參數值(如W[i] += ε),但必須恢復原值,否則后續計算其他參數梯度時會使用已污染的參數值,導致誤差累積。
保持計算獨立性:每次擾動僅針對一個參數分量,其他參數需保持原值,確保梯度計算的正確性。
2. 優化算法中的歷史權重保存
在部分高級優化算法(如動量法、Adam)中,需保存歷史梯度或權重信息,以加速收斂或穩定訓練。
作用:自適應調整各參數的學習率,適合稀疏梯度或非平穩目標函數。
3. 為什么需要用更新后的數據梯度下降?
梯度下降的核心邏輯是 “用當前參數計算梯度,再更新參數”。
數據更新:每次迭代使用當前批次的數據(如Mini-Batch)計算梯度,確保參數朝著當前數據分布下的最優方向更新。
時序性:若使用舊數據(如過時的權重或歷史批次數據),梯度方向可能偏離真實分布,導致收斂緩慢或不穩定。
2、正確代碼示例
修正方法
對每個參數單獨定義閉包函數,在計算時臨時修改網絡參數:
def numerical_gradient(self, x, t):grads = {}# 計算 W1 的梯度def loss_W1(W):original = self.params['W1'].copy()self.params['W1'] = W # 臨時修改參數loss = self.loss(x, t)self.params['W1'] = original # 恢復原始參數return lossgrads['W1'] = numerical_gradient(loss_W1, self.params['W1'])# 類似地處理 b1、W2、b2...return grads