貝葉斯優化(Bayesian Optimization)只需要看這一篇就夠了,算法到python實現


貝葉斯優化 (BayesianOptimization)

1 問題提出

神經網咯是有許多超參數決定的,例如網絡深度,學習率,正則等等。如何尋找最好的超參數組合,是一個老人靠經驗,新人靠運氣的任務。

窮舉搜索 Grid Search 效率太低;隨機搜索比窮舉搜索好一點;目前比較好的解決方案是貝葉斯優化

1.1 貝葉斯優化的優點

  • 貝葉斯調參采用高斯過程,考慮之前的參數信息,不斷地更新先驗;網格搜索未考慮之前的參數信息
  • 貝葉斯調參迭代次數少,速度快;網格搜索速度慢,參數多時易導致維度爆炸
  • 貝葉斯調參針對非凸問題依然穩健;網格搜索針對非凸問題易得到局部優最

2 詳細算法

這個博客寫的不錯,但是需要一定的數學基礎

3 python實現

3.1 貝葉斯初步優化

這里本來想用kaggle的lgb貝葉斯優化,但是對新手不太友好,就使用這個博客中的例子

  1. 安裝
pip install bayesian-optimization
  1. 准備工作(使用隨機森林作為模型進行參數優化)
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.cross_validation import cross_val_score
from bayes_opt import BayesianOptimization

# 產生隨機分類數據集,10個特征, 2個類別
x, y = make_classification(n_samples=1000,n_features=10,n_classes=2)

sklearn.cross_validation 已經廢棄,改為:sklearn.model_selection
不調參數的結果:

rf = RandomForestClassifier()
print(np.mean(cross_val_score(rf, x, y, cv=20, scoring='roc_auc')))

>>> 0.965162
  1. 貝葉斯優化
    先要定義一個目標函數。比如此時,函數輸入為隨機森林的所有參數,輸出為模型交叉驗證5次的AUC均值,作為我們的目標函數。因為bayes_opt庫只支持最大值,所以最后的輸出如果是越小越好,那么需要在前面加上負號,以轉為最大值。
def rf_cv(n_estimators, min_samples_split, max_features, max_depth):
    val = cross_val_score(
        RandomForestClassifier(n_estimators=int(n_estimators),
            min_samples_split=int(min_samples_split),
            max_features=min(max_features, 0.999), # float
            max_depth=int(max_depth),
            random_state=2
        ),
        x, y, scoring='roc_auc', cv=5
    ).mean()
    return val

建立貝葉斯優化對象

 rf_bo = BayesianOptimization(
        rf_cv,
        {'n_estimators': (10, 250),
        'min_samples_split': (2, 25),
        'max_features': (0.1, 0.999),
        'max_depth': (5, 15)}
    )

里面的第一個參數是我們的優化目標函數,第二個參數是我們所需要輸入的超參數名稱,以及其范圍。超參數名稱必須和目標函數的輸入名稱一一對應。

開始優化:

rf_bo.maximize()

優化結果:

|   iter    |  target   | max_depth | max_fe... | min_sa... | n_esti... |
-------------------------------------------------------------------------
|  1        |  0.9758   |  7.261    |  0.7852   |  17.35    |  231.3    |
|  2        |  0.9725   |  9.361    |  0.1805   |  12.82    |  185.7    |
|  3        |  0.9761   |  6.576    |  0.6609   |  15.19    |  12.12    |
|  4        |  0.9711   |  6.679    |  0.1358   |  10.07    |  223.1    |
|  5        |  0.9768   |  7.614    |  0.563    |  12.94    |  247.5    |
|  6        |  0.9744   |  14.74    |  0.7134   |  24.53    |  245.1    |
|  7        |  0.953    |  5.275    |  0.1552   |  24.75    |  10.72    |
|  8        |  0.9748   |  5.318    |  0.8218   |  2.634    |  77.82    |
|  9        |  0.9607   |  15.0     |  0.999    |  2.0      |  10.0     |
|  10       |  0.9654   |  5.007    |  0.2314   |  2.315    |  10.24    |
|  11       |  0.9701   |  14.89    |  0.976    |  24.45    |  118.8    |
|  12       |  0.9743   |  14.98    |  0.6535   |  23.94    |  53.86    |
|  13       |  0.972    |  14.09    |  0.7797   |  2.199    |  142.2    |
|  14       |  0.9722   |  14.88    |  0.8909   |  9.471    |  64.05    |
|  15       |  0.976    |  5.195    |  0.8093   |  24.1     |  145.6    |
|  16       |  0.9715   |  5.136    |  0.9308   |  4.38     |  35.74    |
|  17       |  0.9747   |  5.195    |  0.9876   |  24.68    |  78.97    |
|  18       |  0.9747   |  5.249    |  0.9799   |  24.72    |  248.5    |
|  19       |  0.9745   |  5.235    |  0.8297   |  4.737    |  120.6    |
|  20       |  0.9711   |  14.88    |  0.9794   |  23.83    |  179.4    |
|  21       |  0.9739   |  5.495    |  0.9039   |  2.218    |  161.8    |
|  22       |  0.9757   |  8.063    |  0.2147   |  13.45    |  247.3    |
|  23       |  0.9723   |  14.59    |  0.8999   |  2.442    |  249.0    |
|  24       |  0.9741   |  5.035    |  0.8009   |  13.7     |  56.69    |
|  25       |  0.9701   |  13.11    |  0.9747   |  12.36    |  93.52    |
|  26       |  0.9744   |  5.083    |  0.9857   |  24.38    |  205.5    |
|  27       |  0.9741   |  14.99    |  0.7923   |  17.87    |  30.14    |
|  28       |  0.9738   |  5.038    |  0.973    |  13.42    |  142.2    |
|  29       |  0.9724   |  14.81    |  0.7962   |  2.028    |  187.0    |
|  30       |  0.9734   |  5.378    |  0.9614   |  14.71    |  24.68    |
=========================================================================

尋找最大值:

rf_bo.res["max"]

但是我使用這個就會報錯,所以就簡單寫了一個循環尋找最大值的索引:

index = []
for i in rf_bo.res:
    index.append(i['target'])
max_index = index.index(max(index))

3.2 貝葉斯進階優化

上面bayes算法得到的參數並不一定最優,當然我們會遇到一種情況,就是我們已經知道有一組或是幾組參數是非常好的了,我們想知道其附近有沒有更好的。這個操作相當於上文bayes優化中的Explore操作,而bayes_opt庫給了我們實現此方法的函數:

rf_bo.explore(
    {'n_estimators': [10, 100, 200],
        'min_samples_split': [2, 10, 20],
        'max_features': [0.1, 0.5, 0.9],
        'max_depth': [5, 10, 15]
    }
)

這里我們添加了三組較優的超參數,讓其在該參數基礎上進行explore,可能會得到更好的結果。

同時,我們還可以修改高斯過程的參數,高斯過程主要參數是核函數(kernel),還有其他參數可以參考sklearn.gaussianprocess:

gp_param={'kernel':None}
rf_bo.maximize(**gp_param)

如果kernel是None,1.0 * RBF(1.0)被用來當成默認的kernel。

但是從某種角度上來說,貝葉斯優化也是另外一種瞎猜。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM