從入土到入門學習超參數的調整

最近在做第十五屆全國大學生智能汽車競賽線上選拔賽,人流密度檢測這塊的效果一直不好,error_rate越整越大,交流羣裏的大佬也看不下去了:
在這裏插入圖片描述
確實,要是調整調整超參數,也不會是現在這樣的成績(流下了沒技術的眼淚…)

於是,我下定決心,好好地啃啃這塊硬骨頭!(先把自己從土裏拉出來…)

  1. 參數&超參數
  2. 手動調整超參數
  1. 自動優化超參數

在這裏插入圖片描述

在開始之前,首先好好學習一下什麼是參數,什麼又是超參數?

參數&超參數

參數:
模型根據數據可以自動學習出的變量

超參數:
用來確定模型的一些參數

參數

參數是機器學習算法的關鍵,是從訓練數據中學習到的,屬於模型的一部分。

不知道大家還記得權重嗎?
適合新手入門且最簡單的ANN人工神經網絡模型(Python)

看看這篇文章裏講到的只有一個神經元的神經網絡的權重:
在這裏插入圖片描述
輸入一個值(x),乘以權重,結果就是網絡的輸出值。權重可以隨着網絡的訓練進行更新,從而找到最佳的值,這樣網絡就能嘗試匹配輸出值與目標值。

下面再來看一下更復雜的網絡:
在這裏插入圖片描述
爲了得到預期的輸出結果,將權重初始化後,權重可以隨着網絡的訓練進行更新,從而找到最佳的值,這樣網絡就能嘗試匹配輸出值與目標值,從而得到預期的結果。

這裏的權重其實就是一種參數

超參數

模型的超參數指的是模型外部的配置變量,是不能通過訓練的進行來估計其取值不同的,且不同的訓練任務往往需要不同的超參數

超參數不同,最終得到的模型也是不同的。

一般來說,超參數有:學習率,迭代次數,網絡的層數,每層神經元的個數等等。

常見的超參數有以下三類:

  1. 網絡結構,包括神經元之間的連接關係、層數、每層的神經元數量、激活函數的類型等 .
  2. 優化參數,包括優化方法、學習率、小批量的樣本數量等 .
  3. 正則化係數

實踐中,當你使⽤神經⽹絡解決問題時,尋找好的超參數其實是一件非常困難的事情,對於剛剛接觸的同學來說,都是"佛系調優",這也是一開始就"入土"的原因,沒有依據的盲目瞎調肯定是不行的。

手動調整超參數

我們在使用某一網絡時,一般是比較好的論文中出現過的,是證明過的,當然也可以直接套用,然後在這個基礎上,調參。

可是如果識別的領域不同,比如同樣是LeNet網絡,在解決手寫數字識別時使用的超參數能得到很好的效果,但是在做眼疾識別時,因爲數據集的不同,雖然使用同樣的超參數,但是效果可能並不理想。

在<< Neural Network and Deep Learning >>這本書中,作者給出⼀些⽤於設定超參數的啓發式想法。⽬的是幫讀者發展出⼀套⼯作流來確保很好地設置超參數。這裏我把書上的內容總結一下,再結合自己的思考,與大家共同探討調整超參數的方法論。

不過呢,目前不存在⼀種通⽤的關於正確策略的共同認知,這也是超參數調節的"玄學"之處

  1. 使⽤提前停⽌來確定訓練的迭代期數量
  2. 讓學習率從高逐漸降低
  3. 寬泛策略
  4. 小批量數據(mini-batch)大小不必最優
  5. 發展出⼀個確保自己能快速進行超參數優化的工作流

使⽤提前停止來確定訓練的迭代期數量

這個策略是我的老師最早教我的,個人認爲這也是防止過擬合最直接的方式

做法其實很簡單,做一個判斷,滿足條件時退出循環,終止訓練:

for epoch in range(MAX_EPOCH):
	// 訓練代碼
	print('{}[TRAIN]epoch {}, iter {}, output loss: {}'.format(timestring, epoch, i, loss.numpy()))
	if ():
		break
	model.train()

那麼這個if條件判斷就十分重要了,這裏有兩種方案:

  1. 分類準確率不再提升時
  2. loss降到一個想要的範圍時

1. 分類準確率不再提升時

方案一是書中給的方法。

我們需要再明確⼀下什麼叫做分類準確率不再提升,這樣⽅可實現提前停⽌。

我們知道,分類準確率在整體趨勢下降的時候仍舊會抖動或者震盪。如果我們在準確度剛開始下降的時候就停⽌,那麼肯定會錯過更好的選擇。⼀種不錯的解決⽅案是如果分類準確率在⼀段時間內不再提升的時候終⽌。

當然這塊用loss也是可以的,loss也是一個評判標準

2. loss降到一個想要的範圍時

方案二是我經常使用的、更直接的方法。

比如在前幾輪的訓練中,我知道loss一直在2.6-2.7的附近徘徊:
在這裏插入圖片描述
在下一次訓練中,可以把條件設置爲當loss小於2.0時終止訓練

因爲⽹絡有時候會在很⻓時間內於⼀個特定的分類準確率附近形成平緩的局⾯,然後纔會有提升。如果你想獲得相當好的性能,方案一的規則可能就會太過激進了 —— 停⽌得太草率。

方案二能很好地解決這一問題,但隨之而來的問題就是不知不覺地又多了一個超參數,實際應用上,這個用於條件判斷的loss值的選擇也很困難。

讓學習率從高逐漸降低

我們⼀直都將學習速率設置爲常量。但是,通常採⽤可變的學習速率更加有
效。

如果學習率設置的過低,在訓練的前期,訓練速度會非常慢;而學習率設置地過高,在訓練的後期,又會產生震盪,降低模型的精度:
在這裏插入圖片描述

所以最好是在前期使⽤⼀個較⼤的學習速率讓權重變化得更快。越往後,我們可以降低學習速率,這樣可以作出更加精良的調整。

⼀種⾃然的觀點是使⽤提前終⽌的想法。就是保持學習速率爲⼀個常量直到驗證準確率開始變差,然後按照某個量下降學習速率。我們重複此過程若⼲次,直到學習速率是初始值的 1/1024(或者1/1000),然後終⽌訓練。

寬泛策略

在使⽤神經網絡來解決新的問題時,⼀個挑戰就是獲得任何⼀種⾮尋常的學習,也就是說,達到⽐隨機的情況更好的結果。

也許下面的方法能給你帶來某些不一樣的啓發:

  1. 通過簡化網絡來加速實驗進⾏更有意義的學習
  2. 通過更加頻繁的監控驗證準確率來獲得反饋

通過簡化網絡來加速實驗進⾏更有意義的學習

假設,我們第⼀次遇到 MNIST 分類問題。剛開始,你很有激情,但是當模型完全失效時,你會就得有些沮喪。

此時就可以將問題簡化,將十分類問題轉化成二分類問題。丟開訓練和驗證集合中的那些除了 0 和 1的那些圖像,即我們只識別0和1。然後試着訓練⼀個⽹絡來區分 0 和 1。

這樣一來,不僅僅問題⽐ 10 個分類的情況簡化了,同樣也會減少 80% 的訓練數據,這樣就多出了 5 倍的加速。同時也可以保證更快的實驗,也能給予你關於如何構建好的⽹絡更快的洞察。

通過更加頻繁的監控驗證準確率來獲得反饋

這個方法調的其實是輸出:

if i % 200 == 0:
	timestring = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
	print('{}[VALID]epoch {}, iter {}, output loss: {}'.format(timestring, epoch, i, loss.numpy()))

對模型本身並沒有任何關係,但是,你能得到更多並且更快地得到反饋,從而快速地實驗其他的超參數,或者甚⾄近同步地進⾏不同參數的組合的評⽐。

這一點看似不重要,但對於超參數的調整來說,是很重要的一步

因爲在實際的應用中,很容易會遇到神經⽹絡學習不到任何知識的情況。你可能要花費若干天在調整參數上,仍然沒有進展。所以在前期的時候,就應該從實驗中儘可能早的獲得快速反饋。直覺上看,這看起來簡化問題和架構僅僅會降低你的效率。而實際上,這樣能夠將進度加快,因爲你能夠更快地找到傳達出有意義的信號的網絡。⼀旦你獲得這些信號,你可以嘗試通過微調超參數獲得快速的性能提升。

這和人生中很多情況⼀樣 —— 萬事開頭難。

小批量數據(mini-batch)大小不必最優

假設我們使⽤大小爲 1 的小批量數據。而一般來說,使用只有⼀個樣本的小批量數據會帶來關於梯度的錯誤估計

而實際上,誤差並不會真的產⽣這個問題。原因在於單⼀的梯度估計不需要絕對精確。我們需要的是確保代價函數保持下降足夠精確的估計。

這就好像你現在要去北極點,但是隻有⼀個不⼤精確的指南針。如果你不再頻繁地檢查指南針,指南針會在平均狀況下給出正確的⽅向,所以最後你也能抵達北極點。

不過使用更⼤的小批量數據看起來還是顯著地能夠進⾏訓練加速的。

所以,選擇最好的小批量數據大小是⼀種折中。小批量數據太小會加長訓練時間;而小批量數據太大是不能夠足夠頻繁地更新權重的。你所需要的是選擇⼀個折中的值,可以最大化學習的速度。

幸運的是,小批量數據大小的選擇其實是相對獨⽴的⼀個超參數(⽹絡整體架構外的參數),所以你不需要優化那些參數來尋找好的小批量數據大小。

因此,可以選擇的⽅式就是使⽤某些可以接受的值(不需要是最優的)作爲其他參數的選擇,然後進⾏不同小批量數據大小的嘗試,就像上面調整學習率那樣,畫出驗證準確率的值隨時間(非回合)變化的圖,選擇得到最快性能提升的小批量數據大小。

發展出⼀個確保自己能快速進行超參數優化的工作流

超參數優化不是⼀個已經被完全解決的問題。總有⼀些技巧能夠嘗試着來提升性能。有句關於作家的諺語是:“書從來不會完結,只會被丟棄。”這點在神經⽹絡優化上也是⼀樣的:超參數的空間太大了,所以⼈們無法真的完成優化,只能將問題丟給後⼈。

所以你的目標應是發展出⼀個工作作流來確保自己快速地進行參數優化,這樣可以留有足夠夠的靈活性空間來嘗試對重要的參數進行更加細節的優化。

自動優化超參數

超參數優化( Hyperparameter Optimization )主要存在兩方面的困難 :

  1. 超參數優化是一個組合優化問題,無法像一般參數那樣通過梯度下降方法來優化,也沒有一種通用有效的優化方法
  2. 評估一組超參數配置的時間代價非常高,從而導致一些優化方法在超參數優化中難以應用

常見的優化方法主要有:

  1. 網格搜索
  2. 隨機搜索
  3. 貝葉斯優化
  4. 動態資源分配
  5. 神經架構搜索

1. 網格搜索

網格搜索( Grid Search )是一種通過嘗試所有超參數的組合來尋址合適一
組超參數配置的方法。網格搜索根據這些超參數的不同組合分別訓練一個模型,然後測試這些模型在開發集上的性能,選取一組性能最好的配置 。

說的直接一點就是窮舉法

我們在搜索超參數的時候,如果超參數個數較少(3-4個或者更少),那麼我們可以採用網格搜素,一種窮盡式的搜索方法。

但是當超參數個數比較多的時候,我們仍然採用網格搜索,那麼搜索所需時間將會指數級上升。

比如我們有四個超參數,每個範圍都是[10,100],那麼我們所需的搜索次數是101010*10=10^4

如果再增加一個超參數,那麼所需的搜索次數是10^5,搜索時間指數級上升。

2. 隨機搜索

不同超參數對模型性能的影響有很大差異 。有些超參數(比如正則化係數)
對模型性能的影響有限,而另一些超參數(比如學習率)對模型性能影響比較大 。在這種情況下,採用網格搜索會在不重要的超參數上進行不必要的嘗試 。

一種在實踐中比較有效的改進方法是對超參數進行隨機組合,然後選取一個性能最好的配置,這就是隨機搜索( Random Search )。

隨機搜索在實踐中更容易實現,一般會比網格搜索更加有效 。

然而網格搜索和隨機搜索都沒有利用不同超參數組合之間的相關性,即如果模型的超參數組合比較類似,其模型性能也是比較接近的 。因此這兩種搜索方式一般都比較低效。

另外,這兩種方法都有一個比較大的缺陷:資源浪費

這兩種方法只有一小部分神經網絡將被優質的超參數訓練,但是剩下大部分網絡無法接受更好的訓練,因此這種方法浪費計算資源。

3. 貝葉斯優化

貝葉斯優化( Bayesian optimization )是一種自適應的超參數優化方法,根據當前已經試驗的超參數組合,來預測下一個可能帶來最大收益的組合 。

這種搜索策略是建立一個代理模型,試圖從超參數配置中預測我們關心的度量指標。在每一次迭代中,代理將會變得越來越有信心,新的猜測會帶來新的改進。

要想搞明白貝葉斯優化,就要明白什麼是高斯過程:

高斯過程( Gaussian Process )會產生預測值,同時還會給我們一個不確定性的範圍,通常是均值和方差。

新的超參數就從這個不確定的範圍裏取出,相比隨機搜索,貝葉斯優化更具有目標性

4. 動態資源分配

在超參數優化中,每組超參數配置的評估代價比較高。如果我們可以在較早
的階段就估計出一組配置的效果會比較差,那麼我們就可以中止這組配置的評估,將更多的資源留給其他配置。

這個問題可以歸結爲多臂賭博機問題的一個泛化問題:最優臂問題( Best-Arm Problem ),即在給定有限的機會次數下,如何玩這些賭博機並找到收益最大的臂。和多臂賭博機問題類似,最優臂問題也是在利用和探索之間找到最佳的平衡。

由於目前神經網絡的優化方法一般都採取隨機梯度下降,因此我們可以通過一組超參數的學習曲線來預估這組超參數配置是否有希望得到比較好的結果。

如果一組超參數配置的學習曲線不收斂或者收斂比較差,我們可以應用早期停止( Early-Stopping )策略來中止當前的訓練。

動態資源分配的關鍵是將有限的資源分配給更有可能帶來收益的超參數組
合。 一種有效方法是逐次減半( SuccessiveHalving )方法,將超參數優化看作是一種非隨機的最優臂問題。

在逐次減半方法中,嘗試的超參數配置數量十分關鍵。如果數量越大,得到最佳配置的機會也越大,但每組配置分到的資源就越少,這樣早期的評估結果可能不準確。反之如果超參數的數量越小,每組超參數配置的評估會越準確,但有可能無法得到最優的配置。

5. 神經架構搜索

上面介紹的超參數優化方法都是在固定(或變化比較小)的超參數空間中進行最優配置搜索,而最重要的神經網絡架構一般還是需要由有經驗的專家來
進行設計。從某種角度來講,深度學習使得機器學習中的“特徵工程”問題轉變爲“網絡架構工程”問題 。

神經架構搜索( Neural Architecture Search , NAS )是一個新的比較有前景的研究方向,通過神經網絡來自動實現網絡架構的設計。一個神經網絡的架構可以用一個變長的字符串來描述。利用元學習的思想,神經架構搜索利用一個控制器來生成另一個子網絡的架構描述。 控制器可以由一個循環神
經網絡來實現。控制器的訓練可以通過強化學習來完成,其獎勵信號爲生成的子網絡在開發集上的準確率 。

神經架構搜索的原理是給定一個稱爲搜索空間的候選神經網絡結構集合,用某種策略從中搜索出最優網絡結構。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章