超參數優化
Bayesian Optimization使用Hyperopt進行參數調優
1. 前言
現在的機器學習和深度學習中,在模型結構确定的情況下,不同的超參數的選擇對整個結果的好壞有着至關重要的影響。不少人還嬉稱人工智能工程師,其實是“調參俠”。
1.1 超參數
- 在模型開始學習過程之前人為設定值的參數,而不是(像bias、weights)通過訓練可得到的參數資料。
- 這些參數定義關于模型更高層次的概念(模型複雜性、學習能力等)。
- 比如說随機梯度下降算法中的學習速率/learning rate,出于計算複雜度和算法效率等,我們并不能從資料中直接學習一個比較不錯的學習速度。但學習速率卻又是十分重要的,較大的學習速率不易令模型收斂到較合适的較小值解,而較小的學習速率卻又常常令模型的訓練速度大大降低。對于像學習速率這樣的超參數,我們通常需要在訓練模型之前設定。是以,對于超參數衆多的複雜模型,調超參技能顯得很重要。
2. Grid Search
Grid Search用的是窮舉搜尋:在所有候選的參數選擇中,通過循環周遊,嘗試每一種可能性,表現最好的參數就是最終的結果。其原理就像是在數組裡找最大值。(為什麼叫網格搜尋?以有兩個參數的模型為例,參數a有3種可能,參數b有4種可能,把所有可能性列出來,可以表示成一個3*4的表格,其中每個cell就是一個網格,循環過程就像是在每個網格裡周遊、搜尋,是以叫grid search)
- 搜尋整個超參數空間,在高維空間容易遇到次元災難,不實用。
- 網格搜尋是一種昂貴的方法。假設我們有n個超參數,每個超參數有兩個值,那麼配置總數就是2的N次方。是以,僅在少量配置上進行網格搜尋是可行的。
- 網格搜尋可以并行化,使得網格搜尋在足夠的計算能力下更加可行。
- 每次trial之間是互相獨立的,不能利用先驗知識選擇下一組超參數。
3. Random Search
随機搜尋是一種在巨大資料規模下執行一個耗時上無法接受的程式的優化方法。
- 資料規模大,精确的結果難以在一定時間計算出。
- 結果的些許的不精确能夠被接受。
- 求取的結果是最優化(optimization)問題,有一個成本計算模型。
随機搜尋的算法類型:
- 基本随機搜尋
- 爬山搜尋算法
- 模拟退火算法
- 遺傳算法
4. GridSearch和RandomSearch的使用
這裡給出一個GridSearch和RandomSearch的簡單使用方式,友善同學們測試功能用。
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets
from sklearn.model_selection import GridSearchCV,RandomizedSearchCV
from sklearn.model_selection import train_test_split
# 加載資料集
iris = datasets.load_iris()
data = iris.data
label = iris.target
# 資料集分割
X_train,X_test,y_train,y_test = train_test_split(data,label,test_size=0.3,random_state=2)
knn_clf_orogin = KNeighborsClassifier()
# 搜尋的超參數範圍
param_grid ={
'weights':['distance'],
'n_neighbors':[i for i in range(1,11)],
'p':[i for i in range(1,6)]
}
grid_search = GridSearchCV(knn_clf,param_grid,n_jobs=-1,verbose=2)
grid_search.fit(X_train,y_train)
knn_clf1 = grid_search.best_estimator_
y_pre = knn_clf1.predict(X_test)
knn_clf1.score(X_test,y_pre)
# print('grid_search-度量記錄:',grid_search.cv_results_)
print('grid_search-最佳路徑成本:',grid_search.best_score_)
print('grid_search-最佳參數:',grid_search.best_params_)
print('grid_search-最佳模型:',grid_search.best_estimator_)
random_search = RandomizedSearchCV(knn_clf_orogin,param_grid,n_jobs=-1,verbose=2)
random_search.fit(X_train,y_train)
knn_clf2 = random_search.best_estimator_
y_pre = knn_clf2.predict(X_test)
knn_clf2.score(X_test,y_pre)
# print('random_search-度量記錄:',random_search.cv_results_)
print('random_search-最佳路徑成本:',random_search.best_score_)
print('random_search-最佳參數:',random_search.best_params_)
print('random_search-最佳模型:',random_search.best_estimator_)
雖然随機搜尋得到的結果互相之間差異較大,但是實驗證明随機搜尋的确比網格搜尋效果要好。
5. Bayesian Optimization
貝葉斯優化其實就是基于模型的超參數優化,根據已有的采樣點預估函數,不斷疊代獲得最大值的一個算法。
5.1 Bayesian Optimization流程圖
5.2 算法步驟
- \(f\)是我們的的預估函數,也可以是一個黑盒的模型。
- \(X\)是自定義的輸入參數的範圍
- \(S\)是Acquisition Function(采集函數),這個函數的作用是通過最大化AF來選擇下一個采樣點。
- \(M\)是先驗函數(Prior Function,PF),可以通過\(M\)和\(X\)計算得出具體的模型具體函數表示。
- 模型步驟解析:
- 通過\(INITSAMPLES(f,X)\)采集初始的樣本\(D={(x_1,y_1),(x_2,y_2)...(x_i,y_i)}\)
- 循環選參數\(T\)次:
- 通過\(FITMODEL(M,D)\)計算出\(p(y|x,D)\)的機率。
- 通過\(S\)的采集函數計算出\(y\)取值最大時的\(x_i\)。
- 判斷\(y_i\)值是否滿足要求。
- 如果不滿足要求,繼續計算整個過程。
5.3 優點
- 貝葉樹優化和網格搜尋相比,疊代次數少(節省時間),粒度可以到很小。
- 搜尋方式自動化,不需要太多人工參與。
- 調參過程可以控制。
5.4 缺點
- 不容易找到全局最優解。
- 過程比較複雜。