《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數

哈工大SCIR發表於2016-11-05


文章出處: Michael Nielsen的《Neural Network and Deep Learning》,本節譯者:朱小虎 、張廣宇。


目錄

1、使用神經網路識別手寫數字

2、反向傳播演算法是如何工作的

3、改進神經網路的學習方法

  • 改進神經網路的學習方式
  • 交叉熵損失函式
  • 使用交叉熵損失來分類MNIST數字集
  • 交叉熵意味著什麼?它從哪裡來?
  • Softmax
  • 過擬合和正則化
  • 正則化
  • 為什麼正則化能夠降低過擬合?
  • 其他正則化技術
  • 引數初始化
  • 重溫手寫數字識別:程式碼
  • 如何選擇神經網路的超引數
  • 其他技術

4、神經網路能夠計算任意函式的視覺證明

5、為什麼深度神經網路的訓練是困難的

6、深度學習


直到現在,我們還沒有解釋對諸如學習速率 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,規範化引數 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 等等超引數選擇的方法。我只是給出那些效果很好的值而已。實踐中,當你使用神經網路解決問題時,尋找好的超引數其實是很困難的一件事。例如,我們要解決 MNIST 問題,開始時對於選擇什麼樣的超引數一無所知。在之前的實驗中我們靠運氣選擇了一些引數設定:30個隱層,小批量資料大小為10,迭代訓練30輪,使用交叉熵損失函式。但是,在使用學習速率 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 而規範化引數 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數時,我們的一個執行結果如下:


>>> import mnist_loader
>>> training_data, validation_data, test_data = \
... mnist_loader.load_data_wrapper()
>>> import network2
>>> net = network2.Network([784, 30, 10])
>>> net.SGD(training_data, 30, 10, 10.0, lmbda = 1000.0,
... evaluation_data=validation_data, monitor_evaluation_accuracy=True)
Epoch 0 training complete
Accuracy on evaluation data: 1030 / 10000
Epoch 1 training complete
Accuracy on evaluation data: 990 / 10000
Epoch 2 training complete
Accuracy on evaluation data: 1009 / 10000
...
Epoch 27 training complete
Accuracy on evaluation data: 1009 / 10000
Epoch 28 training complete
Accuracy on evaluation data: 983 / 10000
Epoch 29 training complete
Accuracy on evaluation data: 967 / 10000


我們分類準確率並不比隨機選擇更好。網路就像隨機噪聲產生器一樣。


你可能會說,“這好辦,降低學習速率和規範化引數就好了。”不幸的是,你並不先驗地知道這些就是需要調整的超引數。可能真正的問題出在  個隱藏元中,本身就不能很有效,不管我們如何調整其他的超引數都沒有作用的?可能我們真的需要至少 個隱藏神經元?或者是  個隱藏神經元?或者更多層的網路?或者不同輸出編碼方式?可能我們的網路一直在學習,只是學習的回合還不夠?可能 minibatch 設的太小了?可能我們需要切換成二次代價函式?可能我們需要嘗試不同的權重初始化方法?等等。很容易就在超引數的選擇中迷失了方向。如果你的網路規模很大,或者使用了很多的訓練資料,這種情況就很令人失望了,因為一次訓練可能就要幾個小時甚至幾天乃至幾周,最終什麼都沒有獲得。如果這種情況一直髮生,就會打擊你的自信心。可能你會懷疑神經網路是不是適合你所遇到的問題?可能就應該放棄這種嘗試了?


本節,我會給出一些用於設定超引數的啟發式想法。目的是幫你發展出一套工作流來確保很好地設定超引數。當然,我不會覆蓋超引數優化的每個方法。那是太繁重的問題,而且也不會是一個能夠完全解決的問題,也不存在一種通用的關於正確策略的共同認知。總是會有一些新的技巧可以幫助你提高一點效能。但是本節的啟發式想法能幫你開個好頭。


寬泛策略: 在使用神經網路來解決新的問題時,一個挑戰就是獲得任何一種非尋常的學習,也就是說,達到比隨機的情況更好的結果。這個實際上會很困難,尤其是遇到一種新型別的問題時。讓我們看看有哪些策略可以在面臨這類困難時候嘗試。


假設,我們第一次遇到 MNIST 分類問題。剛開始,你很有激情,但是當第一個神經網路完全失效時,你會覺得有些沮喪。此時就可以將問題簡化。丟開訓練和驗證集合中的那些除了 和  的那些影像。然後試著訓練一個網路來區分  和 。不僅僅問題比 個分類的情況簡化了,同樣也會減少 80% 的訓練資料,這樣就給出了  倍的加速。這樣可以保證更快的實驗,也能給予你關於如何構建好的網路更快的洞察。


你通過簡化網路來加速實驗進行更有意義的學習。如果你相信 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的網路更可能比隨機更加好的分類效果,那麼就從這個網路開始實驗。這會比訓練一個 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數的網路更快,你可以進一步嘗試後一個。


你可以通過提高監控的頻率來在試驗中獲得另一個加速了。在 network2.py中,我們在每個訓練的回合的最後進行監控。每回合 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,在接受到網路學習狀況的反饋前需要等上一會兒——在我的筆記本上訓練 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 網路基本上每回合 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數秒。當然,《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 秒並不太長,不過你希望嘗試幾十種超引數就很麻煩了,如果你想再嘗試更多地選擇,那就相當棘手了。我們可以通過更加頻繁地監控驗證準確率來獲得反饋,比如說在每 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 次訓練影像後。而且,與其使用整個 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 幅影像的驗證集來監控效能,我們可以使用 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 幅影像來進行驗證。真正重要的是網路看到足夠多的影像來做真正的學習,獲得足夠優秀的估計效能。當然,我們的程式 network2.py 並沒有做這樣的監控。但是作為一個湊合的能夠獲得類似效果的方案,我們將訓練資料減少到前《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 幅 MNIST 訓練影像。讓我們嘗試一下,看看結果。(為了讓程式碼更加簡單,我並 沒有取僅僅是 0 和 1 的影像。當然,那樣也是很容易就可以實現)。


>>> net = network2.Network([784, 10])
>>> net.SGD(training_data[:1000], 30, 10, 10.0, lmbda = 1000.0, \
... evaluation_data=validation_data[:100], \
... monitor_evaluation_accuracy=True)
Epoch 0 training complete
Accuracy on evaluation data: 10 / 100
Epoch 1 training complete
Accuracy on evaluation data: 10 / 100
Epoch 2 training complete
Accuracy on evaluation data: 10 / 100
...


我們仍然獲得完全的噪聲!但是有一個進步:現在我們每一秒鐘可以得到反饋,而不是之前每 10 秒鐘才可以。這意味著你可以更加快速地實驗其他的超引數,或者甚至接近同步地進行不同引數的組合的評比。


在上面的例子中,我設定 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,跟我們之前一樣。但是因為這裡改變了訓練樣本的個數,我們必須對 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 進行調整以保證權重下降的同步性。這意味著改變《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。如果我們這樣設定,則有:


>>> net = network2.Network([784, 10])
>>> net.SGD(training_data[:1000], 30, 10, 10.0, lmbda = 20.0, \
... evaluation_data=validation_data[:100], \
... monitor_evaluation_accuracy=True)
Epoch 0 training complete
Accuracy on evaluation data: 12 / 100
Epoch 1 training complete
Accuracy on evaluation data: 14 / 100
Epoch 2 training complete
Accuracy on evaluation data: 25 / 100
Epoch 3 training complete
Accuracy on evaluation data: 18 / 100
...


哦也!現在有了訊號了。不是非常糟糕的訊號,卻真是一個訊號。我們可以基於這點,來改變超引數從而獲得更多的提升。可能我們猜測學習速率需要增加(你可能會發現,這只是一個不大好的猜測,原因後面會講,但是相信我)所以為了測試我們的猜測就將 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 調整至 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數:


>>> net = network2.Network([784, 10])
>>> net.SGD(training_data[:1000], 30, 10, 100.0, lmbda = 20.0, \
... evaluation_data=validation_data[:100], \
... monitor_evaluation_accuracy=True)
Epoch 0 training complete
Accuracy on evaluation data: 10 / 100
Epoch 1 training complete
Accuracy on evaluation data: 10 / 100
Epoch 2 training complete
Accuracy on evaluation data: 10 / 100
Epoch 3 training complete
Accuracy on evaluation data: 10 / 100
...


​這並不好!告訴我們之前的猜測是錯誤的,問題並不是學習速率太低了。所以,我們試著將《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 將至 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數


>>> net = network2.Network([784, 10])
>>> net.SGD(training_data[:1000], 30, 10, 1.0, lmbda = 20.0, \
... evaluation_data=validation_data[:100], \
... monitor_evaluation_accuracy=True)
Epoch 0 training complete
Accuracy on evaluation data: 62 / 100
Epoch 1 training complete
Accuracy on evaluation data: 42 / 100
Epoch 2 training complete
Accuracy on evaluation data: 43 / 100
Epoch 3 training complete
Accuracy on evaluation data: 61 / 100
...


這樣好點了!所以我們可以繼續,逐個調整每個超引數,慢慢提升效能。一旦我們找到一種提升效能的 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 值,我們就可以嘗試尋找好的值。然後按照一個更加複雜的網路架構進行實驗,假設是一個有 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 個隱藏元的網路。然後繼續調整 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 和 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。接著調整成 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 個隱藏元。然後將其他的超引數調整再調整。如此進行,在每一步使用我們 hold out 驗證資料集來評價效能,使用這些度量來找到越來越好的超引數。當我們這麼做的時候,一般都需要花費更多時間來發現由於超引數改變帶來的影響,這樣就可以一步步減少監控的頻率。


所有這些作為一種寬泛的策略看起來很有前途。然而,我想要回到尋找超引數的原點。實際上,即使是上面的討論也傳達出過於樂觀的觀點。實際上,很容易會遇到神經網路學習不到任何知識的情況。你可能要花費若干天在調整引數上,仍然沒有進展。所以我想要再重申一下在前期你應該從實驗中儘可能早的獲得快速反饋。直覺上看,這看起來簡化問題和架構僅僅會降低你的效率。實際上,這樣能夠將進度加快,因為你能夠更快地找到傳達出有意義的訊號的網路。一旦你獲得這些訊號,你可以嚐嚐通過微調超引數獲得快速的效能提升。這和人生中很多情況一樣——萬事開頭難。


好了,上面就是寬泛的策略。現在我們看看一些具體的設定超引數的推薦。我會聚焦在學習率 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,L2 規範化引數《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,和小批量資料大小。然而,很多的觀點同樣可以應用在其他的超引數的選擇上,包括一些關於網路架構的、其他型別的規範化和一些本書後面遇到的如 momentumco-efficient 這樣的超引數。


學習速率: 假設我們執行了三個不同學習速率(《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數、 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數)的 MNIST 網路。我們會像前面介紹的實驗那樣設定其他的超引數,進行 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合,minibatch 大小為 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,然後 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。我們同樣會使用整個 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 幅訓練影像。下面是一副展示了訓練代價的變化情況的圖:

《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數


使用 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,代價函式平滑下降到最後的回合。使用 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,代價剛開始下降,在大約 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合後接近飽和狀態,後面就是微小的震盪和隨機抖動。最終使用 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 代價從始至終都震盪得非常明顯。為了理解震盪的原因,回想一下隨機梯度下降其實是期望我們能夠逐漸地抵達代價函式的谷底的,

《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數


然而,如果 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 太大的話,步長也會變大可能會使得演算法在接近最小值時候又越過了谷底。這在 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 時非常可能發生。當我們選擇 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數時,初始幾步將我們帶到了谷底附近,但一旦到達了谷底,又很容易跨越過去。而在我們選擇 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 時,在前 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合的訓練中不再受到這個情況的影響。當然,選擇太小的學習速率,也會帶來另一個問題——隨機梯度下降演算法變慢了。一種更加好的策略其實是,在開始時使用 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,隨著越來越接近谷底,就換成《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。這種可變學習速率的方法我們後面會介紹。現在,我們就聚焦在找出一個單獨的好的學習速率的選擇《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數


所以,有了這樣的想法,我們可以如下設定 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。首先,我們選擇在訓練資料上的代價立即開始下降而非震盪或者增加時作為 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的閾值的估計。這個估計並不需要太過精確。你可以估計這個值的量級,比如說從 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 開始。如果代價在訓練的前面若干回合開始下降,你就可以逐步地嘗試 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,直到你找到一個 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的值使得在開始若干回合代價就開始震盪或者增加。相反,如果代價在 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 時就開始震盪或者增加,那就嘗試 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 直到你找到代價在開始回合就下降的設定。按照這樣的方法,我們可以掌握學習速率的閾值的量級的估計。你可以選擇性地優化估計,選擇那些最大的 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,比方說 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 或者 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數(這裡也不需要過於精確)。


顯然,《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 實際值不應該比閾值大。實際上,如果 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的值重複使用很多回合的話,你更應該使用稍微小一點的值,例如,閾值的一半這樣的選擇。這樣的選擇能夠允許你訓練更多的回合,不會減慢學習的速度。


在 MNIST 資料中,使用這樣的策略會給出一個關於學習速率 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的一個量級的估計,大概是 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。在一些改良後,我們得到了閾值 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。所以,我們按照剛剛的取一半的策略就確定了學習速率為 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。實際上,我發現使用《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 在 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合內表現是很好的,所以選擇更低的學習速率,也沒有什麼問題。


這看起來相當直接。然而,使用訓練代價函式來選擇 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 看起來和我們之前提到的通過驗證集來確定超引數的觀點有點矛盾。實際上,我們會使用驗證準確率來選擇規範化超引數,minibatch 大小,和層數及隱藏元個數這些網路引數,等等。為何對學習速率要用不同的方法呢?坦白地說,這些選擇其實是我個人美學偏好,個人習慣罷了。原因就是其他的超引數傾向於提升最終的測試集上的分類準確率,所以將他們通過驗證準確率來選擇更合理一些。然而,學習速率僅僅是偶然地影響最終的分類準確率的。學習速率主要的目的是控制梯度下降的步長,監控訓練代價是最好的檢測步長過大的方法。所以,這其實就是個人的偏好。在學習的前期,如果驗證準確率提升,訓練代價通常都在下降。所以在實踐中使用那種衡量方式並不會對判斷的影響太大。


使用提前停止來確定訓練的迭代次數: 正如我們在本章前面討論的那樣,提前停止表示在每個回合的最後,我們都要計算驗證集上的分類準確率。當準確率不再提升,就終止它。這讓選擇回合數變得很簡單。特別地,也意味著我們不再需要擔心顯式地掌握回合數和其他超引數的關聯。而且,這個過程還是自動的。另外,提前停止也能夠幫助我們避免過度擬合。儘管在實驗前期不採用提前停止,這樣可以看到任何過匹配的訊號,使用這些來選擇規範化方法,但提前停止仍然是一件很棒的事。


我們需要再明確一下什麼叫做分類準確率不再提升,這樣方可實現提前停止。正如我們已經看到的,分類準確率在整體趨勢下降的時候仍舊會抖動或者震盪。如果我們在準確度剛開始下降的時候就停止,那麼肯定會錯過更好的選擇。一種不錯的解決方案是如果分類準確率在一段時間內不再提升的時候終止。例如,我們要解決 MNIST 問題。如果分類準確度在近 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 個回合都沒有提升的時候,我們將其終止。這樣不僅可以確保我們不會終止得過快,也能夠使我們不要一直乾等直到出現提升。


這種 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合不提升就終止的規則很適合 MNIST 問題的一開始的探索。然而,網路有時候會在很長時間內於一個特定的分類準確率附近形成平緩的局面,然後才會有提升。如果你嘗試獲得相當好的效能,這個規則可能就會太過激進了——停止得太草率。所以,我建議在你更加深入地理解網路訓練的方式時,僅僅在初始階段使用 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合不提升規則,然後逐步地選擇更久的回合,比如說: 回合不提升就終止, 回合不提升就終止,以此類推。當然,這就引入了一種新的需要優化的超引數!實踐中,其實比較容易設定這個超引數來獲得相當好的結果。類似地,對不同於 MNIST 的問題, 回合不提升就終止的規則會太過激進或者太過保守,這都取決於問題本身的特質。然而,進行一些小的實驗,發現好的提前終止的策略還是非常簡單的。


我們還沒有在我們的 MNIST 實驗中使用提前終止。原因是我們已經比較了不同的學習觀點。這樣的比較其實比較適合使用同樣的訓練回合。但是,在 network2.py 中實現提前終止還是很有價值的:


問題

1.修改 network2.py 來實現提前終止,並讓 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合不提升終止策略中的 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數稱為可以設定的引數。2.你能夠想出不同於 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合不提升終止策略的其他提前終止策略麼?理想中,規則應該能夠獲得更高的驗證準確率而不需要訓練太久。將你的想法實現在network2.py 中,執行這些實驗和 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合不提升終止策略比較對應的驗證準確率和訓練的回合數。


學習速率調整: 我們一直都將學習速率設定為常量。但是,通常採用可變的學習速率更加有效。在學習的前期,權重可能非常糟糕。所以最好是使用一個較大的學習速率讓權重變化得更快。越往後,我們可以降低學習速率,這樣可以作出更加精良的調整。


我們要如何設定學習速率呢?其實有很多方法。一種自然的觀點是使用提前終止的想法。就是保持學習速率為一個常量直到驗證準確率開始變差。然後按照某個量下降學習速率,比如說按照《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 或者 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。我們重複此過程若干次,直到學習速率是初始值的 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數(或者《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數)。那時就終止。


可變學習速率可以提升效能,但是也會產生大量可能的選擇。這些選擇會讓人頭疼——你可能需要花費很多精力才能優化學習規則。對剛開始實驗,我建議使用單一的常量作為學習速率的選擇。這會給你一個比較好的近似。後面,如果你想獲得更好的效能,值得按照某種規則進行實驗,根據我已經給出的資料。


練習

  • 更改 network2.py 實現學習規則:每次驗證準確率滿足《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 回合不提升終止策略時改變學習速率;當學習速率降到初始值的 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 時終止。

規範化引數: 我建議,開始時不包含規範化(《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數),確定 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數的值。使用確定出來的 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數,我們可以使用驗證資料來選擇好的 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數。從嘗試《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 開始,然後根據驗證集上的效能按照因子 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數增加或減少其值。一旦我已經找到一個好的量級,你可以改進 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的值。這裡搞定後,你就可以返回再重新優化 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數


練習

  • 使用梯度下降來嘗試學習好的超引數的值其實很受期待。你可以想像關於使用梯度下降來確定 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的障礙麼?你能夠想象關於使用梯度下降來確定 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的障礙麼?

在本書前面,我是如何選擇超引數的: 如果你使用本節給出的推薦策略,你會發現你自己找到的  和  不總是和我給出的一致。原因在於書本由於敘事篇幅的限制,有時候會使得優化超引數變得不現實。想想我們已經做過的使用不同觀點學習的對比,比如說,比較二次代價函式和交叉熵代價函式,比較權重初始化的新舊方法,使不使用規範化,等等。為了使這些比較有意義,我通常會將引數在這些方法上保持不變(或者進行合適的尺度調整)。當然,同樣超引數對不同的學習觀點都是最優的也沒有理論保證,所以我用的那些超引數常常是折衷的選擇。


相較於這樣的折衷,其實我本可以嘗試優化每個單一的觀點的超引數選擇。理論上,這可能是更好更公平的方式,因為那樣的話我們可以看到每個觀點的最優效能。但是,我們現在依照目前的規範進行了眾多的比較,實踐上,我覺得要做到需要過多的計算資源了。這也是我使用折衷方式來採用儘可能好(卻不一定最優)的超引數選擇。


小批量資料大小: 我們應該如何設定小批量資料的大小?為了回答這個問題,讓我們先假設正在進行線上學習,也就是說使用大小為 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的小批量資料。


一個關於線上學習的擔憂是使用只有一個樣本的小批量資料會帶來關於梯度的錯誤估計。實際上,誤差並不會真的產生這個問題。原因在於單一的梯度估計不需要絕對精確。我們需要的是確保代價函式保持下降的足夠精確的估計。就像你現在要去北極點,但是隻有一個不大精確的(差個 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 度)指南針。如果你不斷頻繁地檢查指南針,指南針會在平均狀況下給出正確的方向,所以最後你也能抵達北極點。


基於這個觀點,這看起來好像我們需要使用線上學習。實際上,情況會變得更加複雜。在上一章的問題中我指出我們可以使用矩陣技術來對所有在小批量資料中的樣本同時計算梯度更新,而不是進行迴圈。所以,取決於硬體和線性代數庫的實現細節,這會比迴圈方式進行梯度更新快好多。也許是 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 和 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 倍的差別。


現在,看起來這對我們幫助不大。我們使用 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 的小批量資料的學習規則如下;

(1)   《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數

這裡是對小批量資料中所有訓練樣本求和。而線上學習是(2)   《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數即使它僅僅是 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 倍的時間,結果仍然比直接線上學習更好,因為我們線上學習更新得太過頻繁了。假設,在小批量資料下,我們將學習速率擴大了 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 倍,更新規則就是(3)   《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數這看起來項做了 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 次獨立的線上學習。但是僅僅比線上學習花費了 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數倍的時間。當然,其實不是同樣的 100 次線上學習,因為小批量資料中 《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數 是都對同樣的權重進行衡量的,而線上學習中是累加的學習。使用更大的小批量資料看起來還是顯著地能夠進行訓練加速的。


所以,選擇最好的小批量資料大小也是一種折衷。太小了,你不會用上很好的矩陣庫的快速計算。太大,你是不能夠足夠頻繁地更新權重的。你所需要的是選擇一個折衷的值,可以最大化學習的速度。幸運的是,小批量資料大小的選擇其實是相對獨立的一個超引數(網路 整體架構外的引數),所以你不需要優化那些引數來尋找好的小批量資料大小。因此,可以選擇的方式就是使用某些可以接受的值(不需要是最優的)作為其他引數的選擇,然後進行不同小批量資料大小的嘗試,像上面那樣調整 。畫出驗證準確率的值隨時間(非回合)變化的圖,選擇哪個得到最快效能的提升的小批量資料大小。得到了小批量資料大小,也就可以對其他的超引數進行優化了。

當然,你也發現了,我這裡並沒有做到這麼多。實際上,我們的實現並沒有使用到小批量資料更新快速方法。就是簡單使用了小批量資料大小為 。所以,我們其實可以通過降低小批量資料大小來進行提速。我也沒有這樣做,因為我希望展示小批量資料大於 的使用,也因為我實踐經驗表示提升效果其實不明顯。在實踐中,我們大多數情況肯定是要實現更快的小批量資料更新策略,然後花費時間精力來優化小批量資料大小,來達到總體的速度提升。


自動技術: 我已經給出很多在手動進行超引數優化時的啟發式規則。手動選擇當然是種理解網路行為的方法。不過,現實是,很多工作已經使用自動化過程進行。通常的技術就是網格搜尋(grid search),可以系統化地對超引數的引數空間的網格進行搜尋。網格搜尋的成就和限制(易於實現的變體)在 James Bergstra 和 YoshuaBengio 年的論文[1]中已經給出了綜述。很多更加精細的方法也被大家提出來了。我這裡不會給出介紹,但是想指出 2012 年使用貝葉斯觀點自動優化超引數[2]的論文。程式碼可以從(https://github.com/jaberg/hyperopt)獲得,也已經被其他的研究人員使用了。


總結: 跟隨上面的經驗並不能幫助你的網路給出絕對最優的結果。但是很可能給你一個好的開始和一個改進的基礎。特別地,我已經非常獨立地討論了超引數的選擇。實踐中,超引數之間存在著很多關係。你可能使用  進行試驗,發現效果不錯,然後去優化,發現這裡又和  混在一起了。在實踐中,一般是來回往復進行的,最終逐步地選擇到好的值。總之,啟發式規則其實都是經驗,不是金規玉律。你應該注意那些沒有效果的嘗試的訊號,然後樂於嘗試更多試驗。特別地,這意味著需要更加細緻地監控神經網路的行為,特別是驗證集上的準確率。


選擇超引數的難度在於如何選擇超引數的方法太分散, 這些方法分散在許多的研究論文,軟體程式甚至僅僅在一些研究人員的大腦中, 因而變得更加困難。很多很多的論文給出了(有時候矛盾的)建議。然而,還有一些特別有用的論文對這些繁雜的技術進行了梳理和總結。Yoshua Bengio在 2012 年的論文[3]中給出了一些實踐上關於訓練神經網路用到的反向傳播和梯度下降的技術的推薦策略。Bengio 對很多問題的討論比我這裡更加細緻,其中還包含如何進行系統化的超引數搜尋。另一篇非常好的論文是 1998 年的 Yann LeCun、LéonBottou、Genevieve Orr 和 Klaus-Robert Müller 所著的[4]。這些論文蒐集在 2012年的一本書中,這本書介紹了很多訓練神經網路的常用技巧[5]。這本書挺貴的,但很多的內容其實已經被作者共享在網路上了,也許在搜尋引擎上能夠找到一些。在你讀這些文章時,特別是進行試驗時,會更加清楚的是超引數優化就不是一個已經被完全解決的問題。總有一些技巧能夠嘗試著來提升效能。有句關於作家的諺語是:“書從來不會完結,只會被丟棄。”這點在神經網路優化上也是一樣的:超引數的空間太大了,所以人們無法真的完成優化,只能將問題丟給後人。所以你的目標應是發展出一個工作流來確保自己快速地進行引數優化,這樣可以留有足夠的靈活性空間來嘗試對重要的引數進行更加細節的優化。


設定超引數的挑戰讓一些人抱怨神經網路相比較其他的機器學習演算法需要大量的工作進行引數選擇。我也聽到很多不同的版本:“的確,引數完美的神經網路可能會在這問題上獲得最優的效能。但是,我可以嘗試一下隨機森林(或者 SVM 或者……這裡腦補自己偏愛的技術)也能夠工作的。我沒有時間搞清楚那個最好的神經網路。” 當然,從一個實踐者角度,肯定是應用更加容易的技術。這在你剛開始處理某個問題時尤其如此,因為那時候,你都不確定一個機器學習演算法能夠解決那個問題。但是,如果獲得最優的效能是最重要的目標的話,你就可能需要嘗試更加複雜精妙的知識的方法了。如果機器學習總是簡單的話那是太好不過了,但也沒有一個應當的理由說機器學習非得這麼簡單。


[1] http://dl.acm.org/citation.cfm?id=2188395,Random search for hyper-parameter optimization,作者為 James Bergstra 和 Yoshua Bengio (2012)。

[2] http://papers.nips.cc/paper/4522-practical-bayesian-optimization-of-machine-learning-algorithms.pdf,Practical Bayesian optimization of machine learning algorithms,作者為 Jasper Snoek, Hugo Larochelle,和 Ryan Adams。

[3] http://arxiv.org/abs/1206.5533,Practical recommendations for gradient-based training of deep architectures,作者 為 Yoshua Bengio (2012)。

[4] http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf,Efficient BackProp,作者為 Yann LeCun, Léon Bottou, Genevieve Orr 和 Klaus-Robert Müller (1998)。

[5] http://www.springer.com/computer/theoretical+computer+science/book/978-3-642-35288-1,NeuralNetworks: Tricks of the Trade,由 Grégoire Montavon, Geneviève Orr 和 Klaus-Robert Müller 編輯。




本文來源於哈工大SCIR

原文連結點選即可跳轉

《神經網路和深度學習》系列文章三十:如何選擇神經網路的超引數


相關文章