1. 程式人生 > >神經網路中超引數的選擇

神經網路中超引數的選擇

超引數是在開始學習過程之前設定值的引數,而不是通過訓練得到的引數資料。通常情況下,需要對超引數進行優化,給學習機選擇一組最優超引數,以提高學習的效能和效果。

首先需要知道的是並不存在適用於所有場景的超引數,不同的資料集、模型適用的超引數可能不同,因此我們需要嘗試不同的超引數,然後得到最優。

超引數的分類:

一般可以將超引數分為兩類:

  • 優化器超引數:包括學習率、minn_batch大小、迭代的epoch次數;

  • 模型超引數:包括網路層數和隱藏層單元數。

下面開始介紹各個超引數如何在實踐中進行選擇。

1. 學習率:

學習率是一個比較重要的超引數。即便是將別人構建的模型用於自己的資料集,也可能需要嘗試多個不同的學習率。如何選擇正確的學習率?學習率太小,會導致收斂太慢,需要很多的epoch才能到達最優點;而太大會導致越過最優點。比較常見的做法是從0.1開始,然後不斷倍率減小進行嘗試,例如

在實踐中,往往會繪製出損失函式E隨權重變化的函式來確定如何調整超引數。

如果訓練誤差在緩慢 減小,並且訓練完成後仍在減小,可以嘗試增大學習率。

如果訓練誤差在增加,不妨試試減小學習率。

比較好的做法是使學習率能夠自適應調整大小,從而達到最優解。例如:學習率衰減,這麼做的方式是線性降低學習率,例如每五個epoch學習率減半:

或者指數方式降低學習率,例如每8個epoch後學習率乘上0.1:

在TensorFlow中,有一些能夠自適應調整學習率的優化器,例如:

AdamOptimizer

AdagradOptimizer

在實踐中如何調整學習率的兩個例子:

  • 假設你在訓練一個模型。如果訓練過程的輸出如下所示,你將如何調整學習率來 提高訓練效能?  

Epoch 1, Batch 1, Training Error: 8.4181

Epoch 1, Batch 2, Training Error: 8.4177

Epoch 1, Batch 3, Training Error: 8.4177

Epoch 1, Batch 4, Training Error: 8.4173

Epoch 1, Batch 5, Training Error: 8.4169 

答案:提高學習率。因為模型在進行訓練,但速度太慢。提高學習率將使優化器以更大的步長將引數推向最佳值。

  • 假設你在訓練一個模型。如果訓練過程的輸出如下所示,你將如何調整學習率來提高訓練效能?

Epoch 1, Batch 1, Training Error: 8.71
Epoch 1, Batch 2, Training Error: 3.25
Epoch 1, Batch 3, Training Error: 4.93
Epoch 1, Batch 4, Training Error: 3.30
Epoch 1, Batch 5, Training Error: 4.82

答案:降低學習率或者使用自適應學習率。因為誤差瞬間降低然後升高,代表學習率太大,越過了最小值。

2. Mini-batch大小:

mini-batch大小對訓練過程中的資源要求有影響,也會影響訓練速度和迭代次數。

較大的batch大小會使訓練過程中矩陣運算加快,但是也需要佔用更多的記憶體計算空間。遇到記憶體不足或者TensorFlow錯誤,可通過減小batch大小來解決。

較小的batch會使誤差計算有更多的噪聲,並且運算緩慢,而且此噪聲通常有助於防止訓練過程陷入區域性最優。

選擇batch需要根據你的資料集大小和任務進行嘗試。常見的batch大小:

                          1   2   4   8   16   32   64   128   256

通常32 是個不錯的初始選擇,也可以嘗試64,128,256。

3. 迭代次數ecpoch:

要選擇正確的epoch,我們關注的指標應該為驗證誤差。直觀的方法是嘗試不同的epoch,只要驗證誤差還在降低,就繼續迭代。不過我們通常使用一種早期停止的技術,來確定何時停止訓練模型。它的原理是監督驗證誤差,並在驗證誤差停止下降時停止訓練。不過在定義停止觸發器時,可以稍微靈活一點,儘管整體呈下降趨勢,但驗證誤差往往會來回波動,因此我們不能在第一次看到驗證誤差開始增高時就停止訓練,而是如果驗證誤差在最後10步或者20步內沒有任何改進的情況下停止訓練。

在TensorFlow中,可以通過以下方式實現早停。

  • ValidationMonitor,參見文件

來自 ValidationMonitor 文件的以下示例展示了它的設定。注意最後三個引數表示我們正在優化的指標。

validation_monitor = tf.contrib.learn.monitors.ValidationMonitor(
test_set.data,
test_set.target,
every_n_steps=50,
metrics=validation_metrics,
early_stopping_metric="loss",
early_stopping_metric_minimize=True,
early_stopping_rounds=200)

最後一個引數向 ValidationMonitor 表示如果損失未在 200 步(輪)訓練內降低,則停止訓練過程。

然後,validation_monitor 被傳遞給 tf.contrib.learn 的 "fit" 方法,後者執行以下訓練過程:

classifier = tf.contrib.learn.DNNClassifier(
feature_columns=feature_columns,
hidden_units=[10, 20, 10],
n_classes=3,
model_dir="/tmp/iris_model",
config=tf.contrib.learn.RunConfig(save_checkpoints_secs=1))classifier.fit(x=training_set.data,
y=training_set.target,
steps=2000,
monitors=[validation_monitor])
  • SessionRunHook

最近版本的 TensorFlow 廢棄了 Monitor 函式,而採用 SessionRunHooks 。SessionRunHook 是 tf.train 不斷髮展的一部分,往後似乎將是實施早期停止的一個適當位置。

目前為止,tf.train 的訓練鉤子函式 中已存在兩個預定義的停止 Monitor 函式。

StopAtStepHook:用於在特定步數之後要求停止訓練的 Monitor 函式

NanTensorHook:監控損失並在遇到 NaN 損失時停止訓練的 Monitor 函式

4. 隱藏單元/層的數量:

隱藏單元的數量和架構是衡量模型學習能力的主要標準。但是如果模型的學習能力太多,模型會出現過擬合,結果只會適應訓練集而泛化能力弱。如果發現模型出現過擬合,也就是訓練準確度遠高於驗證準確度,你可以嘗試減少隱藏單元數量,當然也可以使用正則化技術。如Dropout或者L2正則化。因此就隱藏單元數量來說,越多越好,稍微超過理想數量不成問題,但是如果過多,會出現過擬合問題,所以你的模型無法訓練,就向它新增更多隱藏層,並跟蹤驗證誤差,持續新增隱藏層單元,直到驗證誤差開始增大。對於第一個隱藏層,有一條經驗是將其設為大於輸入層數量的一個數,

對於神經網路層數的選擇:在實踐中,3 層神經網路的效能通常優於 2 層神經網路,但是更深(4、5、6 層)幫助不大。這與卷積網路形成鮮明對比,卷積神經網路中層數越多相對效能越好,人們發現在卷積網路中深度是對良好的識別系統極其重要的組成部分(例如,10 個可學習層的數量級)。