117 lines
8.5 KiB
Markdown
117 lines
8.5 KiB
Markdown
<!--
|
||
CO_OP_TRANSLATOR_METADATA:
|
||
{
|
||
"original_hash": "ae074cd940fc2f4dc24fc07b66ccbd99",
|
||
"translation_date": "2025-08-26T09:47:22+00:00",
|
||
"source_file": "lessons/4-ComputerVision/08-TransferLearning/TrainingTricks.md",
|
||
"language_code": "mo"
|
||
}
|
||
-->
|
||
# 深度學習訓練技巧
|
||
|
||
隨著神經網絡的深度增加,訓練過程變得越來越困難。一個主要問題是所謂的[梯度消失](https://en.wikipedia.org/wiki/Vanishing_gradient_problem)或[梯度爆炸](https://deepai.org/machine-learning-glossary-and-terms/exploding-gradient-problem#:~:text=Exploding%20gradients%20are%20a%20problem,updates%20are%20small%20and%20controlled)。[這篇文章](https://towardsdatascience.com/the-vanishing-exploding-gradient-problem-in-deep-neural-networks-191358470c11)對這些問題有很好的介紹。
|
||
|
||
為了使深度網絡的訓練更高效,可以使用一些技巧。
|
||
|
||
## 保持數值在合理範圍內
|
||
|
||
為了使數值計算更穩定,我們希望確保神經網絡中的所有數值都在合理的範圍內,通常是 [-1..1] 或 [0..1]。這並不是一個非常嚴格的要求,但浮點數計算的特性是不同量級的數值無法準確地一起操作。例如,如果我們將 10<sup>-10</sup> 和 10<sup>10</sup> 相加,結果可能是 10<sup>10</sup>,因為較小的數值會被“轉換”到與較大的數值相同的量級,從而導致尾數丟失。
|
||
|
||
大多數激活函數在 [-1..1] 範圍內具有非線性特性,因此將所有輸入數據縮放到 [-1..1] 或 [0..1] 範圍是合理的。
|
||
|
||
## 初始權重初始化
|
||
|
||
理想情況下,我們希望數值在通過網絡層後仍保持在相同的範圍內。因此,初始化權重時需要以某種方式保留數值的分佈。
|
||
|
||
正態分佈 **N(0,1)** 不是一個好選擇,因為如果我們有 *n* 個輸入,輸出的標準差將是 *n*,數值可能會跳出 [0..1] 範圍。
|
||
|
||
以下是常用的初始化方法:
|
||
|
||
- 均勻分佈 -- `uniform`
|
||
- **N(0,1/n)** -- `gaussian`
|
||
- **N(0,1/√n_in)** 保證對於均值為零且標準差為 1 的輸入,輸出仍保持相同的均值和標準差
|
||
- **N(0,√2/(n_in+n_out))** -- 所謂的 **Xavier 初始化** (`glorot`),有助於在前向和後向傳播中保持信號在合理範圍內
|
||
|
||
## 批量正規化
|
||
|
||
即使有適當的權重初始化,訓練過程中權重可能會變得非常大或非常小,導致信號超出合理範圍。我們可以通過使用某些**正規化**技術將信號拉回合理範圍。雖然有多種正規化技術(如權重正規化、層正規化),但最常用的是批量正規化。
|
||
|
||
**批量正規化**的核心思想是考慮小批量中的所有數值,並基於這些數值進行正規化(即減去均值並除以標準差)。它被實現為一個網絡層,在應用權重後但在激活函數之前進行正規化。結果通常是更高的最終準確性和更快的訓練速度。
|
||
|
||
以下是批量正規化的[原始論文](https://arxiv.org/pdf/1502.03167.pdf)、[維基百科上的解釋](https://en.wikipedia.org/wiki/Batch_normalization),以及[一篇很好的入門博客文章](https://towardsdatascience.com/batch-normalization-in-3-levels-of-understanding-14c2da90a338)(還有[俄文版](https://habrahabr.ru/post/309302/))。
|
||
|
||
## Dropout
|
||
|
||
**Dropout** 是一種有趣的技術,在訓練過程中隨機移除一定比例的神經元。它也被實現為一個層,具有一個參數(移除神經元的百分比,通常是 10%-50%),在訓練過程中,它會將輸入向量的隨機元素設為零,然後再傳遞到下一層。
|
||
|
||
雖然這聽起來可能有些奇怪,但你可以在 [`Dropout.ipynb`](../../../../../lessons/4-ComputerVision/08-TransferLearning/Dropout.ipynb) 筆記本中看到 Dropout 對訓練 MNIST 數字分類器的影響。它加速了訓練,並使我們能在更少的訓練迭代中達到更高的準確性。
|
||
|
||
這種效果可以從以下幾個方面解釋:
|
||
|
||
- 它可以被認為是對模型的一種隨機衝擊,將優化過程從局部最小值中拉出
|
||
- 它可以被認為是*隱式模型平均化*,因為我們可以說在 Dropout 過程中,我們正在訓練稍微不同的模型
|
||
|
||
> *有人說,當一個醉酒的人試圖學習某些東西時,第二天早上相比清醒的人,他會記得更牢,因為大腦中一些功能失常的神經元會更努力地適應以抓住意義。我們自己從未測試過這是否是真的。*
|
||
|
||
## 防止過擬合
|
||
|
||
深度學習的一個非常重要的方面是能夠防止[過擬合](../../3-NeuralNetworks/05-Frameworks/Overfitting.md)。雖然使用非常強大的神經網絡模型可能很有吸引力,但我們應該始終平衡模型參數的數量與訓練樣本的數量。
|
||
|
||
> 確保你理解我們之前介紹的[過擬合](../../3-NeuralNetworks/05-Frameworks/Overfitting.md)概念!
|
||
|
||
有幾種方法可以防止過擬合:
|
||
|
||
- 提早停止 -- 持續監控驗證集上的錯誤,當驗證錯誤開始增加時停止訓練。
|
||
- 顯式權重衰減 / 正則化 -- 在損失函數中添加額外的懲罰項,用於高絕對值的權重,防止模型產生非常不穩定的結果
|
||
- 模型平均化 -- 訓練多個模型,然後平均結果。這有助於最小化方差。
|
||
- Dropout(隱式模型平均化)
|
||
|
||
## 優化器 / 訓練算法
|
||
|
||
訓練的另一個重要方面是選擇好的訓練算法。雖然經典的**梯度下降**是一個合理的選擇,但有時它可能太慢,或者導致其他問題。
|
||
|
||
在深度學習中,我們使用**隨機梯度下降**(SGD),它是應用於隨機選擇的小批量的梯度下降。權重使用以下公式進行調整:
|
||
|
||
w<sup>t+1</sup> = w<sup>t</sup> - η∇ℒ
|
||
|
||
### 動量
|
||
|
||
在**動量 SGD**中,我們保留了前幾步的部分梯度。這類似於當我們以慣性移動時,受到一個不同方向的衝擊,我們的軌跡不會立即改變,而是保留了一部分原始運動。這裡我們引入另一個向量 v 來表示*速度*:
|
||
|
||
- v<sup>t+1</sup> = γ v<sup>t</sup> - η∇ℒ
|
||
- w<sup>t+1</sup> = w<sup>t</sup>+v<sup>t+1</sup>
|
||
|
||
這裡參數 γ 表示我們考慮慣性程度的大小:γ=0 對應於經典 SGD;γ=1 是純粹的運動方程。
|
||
|
||
### Adam、Adagrad 等
|
||
|
||
由於在每一層中我們將信號乘以某個矩陣 W<sub>i</sub>,根據 ||W<sub>i</sub>||,梯度可能會減小接近 0,或者無限增大。這是梯度爆炸/消失問題的本質。
|
||
|
||
解決這個問題的一種方法是僅使用梯度的方向,而忽略其絕對值,即:
|
||
|
||
w<sup>t+1</sup> = w<sup>t</sup> - η(∇ℒ/||∇ℒ||),其中 ||∇ℒ|| = √∑(∇ℒ)<sup>2</sup>
|
||
|
||
這種算法被稱為 **Adagrad**。其他使用相同思想的算法包括:**RMSProp**、**Adam**
|
||
|
||
> **Adam** 被認為是許多應用中非常高效的算法,因此如果你不確定使用哪個算法,可以選擇 Adam。
|
||
|
||
### 梯度裁剪
|
||
|
||
梯度裁剪是上述思想的擴展。當 ||∇ℒ|| ≤ θ 時,我們在權重優化中使用原始梯度;而當 ||∇ℒ|| > θ 時,我們將梯度除以其範數。這裡 θ 是一個參數,在大多數情況下可以取 θ=1 或 θ=10。
|
||
|
||
### 學習率衰減
|
||
|
||
訓練的成功通常取決於學習率參數 η。邏輯上,較大的 η 值會導致更快的訓練,這是我們通常在訓練初期希望的,而較小的 η 值則允許我們對網絡進行微調。因此,在大多數情況下,我們希望在訓練過程中逐漸減小 η。
|
||
|
||
這可以通過在每次訓練迭代後將 η 乘以某個數字(例如 0.98)來實現,或者使用更複雜的**學習率計劃**。
|
||
|
||
## 不同的網絡架構
|
||
|
||
為你的問題選擇合適的網絡架構可能很棘手。通常,我們會選擇一個已被證明適用於我們特定任務(或類似任務)的架構。這裡有一篇[很好的概述](https://www.topbots.com/a-brief-history-of-neural-network-architectures/)關於計算機視覺中的神經網絡架構。
|
||
|
||
> 選擇一個足夠強大的架構來匹配我們擁有的訓練樣本數量非常重要。選擇過於強大的模型可能會導致[過擬合](../../3-NeuralNetworks/05-Frameworks/Overfitting.md)。
|
||
|
||
另一個好的方法是使用能夠自動調整到所需複雜度的架構。在某種程度上,**ResNet** 架構和 **Inception** 是自我調整的。[更多關於計算機視覺架構的信息](../07-ConvNets/CNN_Architectures.md)。
|
||
|
||
**免責聲明**:
|
||
本文件使用 AI 翻譯服務 [Co-op Translator](https://github.com/Azure/co-op-translator) 進行翻譯。我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。應以原始語言的文件作為權威來源。對於關鍵資訊,建議尋求專業人工翻譯。我們對因使用此翻譯而產生的任何誤解或錯誤解讀概不負責。 |