AI-For-Beginners/translations/mo/lessons/4-ComputerVision/08-TransferLearning/TrainingTricks.md

117 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
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) 進行翻譯。我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。應以原始語言的文件作為權威來源。對於關鍵資訊,建議尋求專業人工翻譯。我們對因使用此翻譯而產生的任何誤解或錯誤解讀概不負責。