超參數優化是深度學習中的重要組成部分
大小:0.3 MB 人氣: 2017-09-30 需要積分:1
標簽:深度學習(119547)
超參數優化是深度學習中的重要組成部分。其原因在于,神經網絡是公認的難以配置,而又有很多參數需要設置。最重要的是,個別模型的訓練非常緩慢。在這篇文章中,你會了解到如何使用scikit-learn python機器學習庫中的網格搜索功能調整Keras深度學習模型中的超參數。
閱讀本文后,你就會了解:
如何包裝Keras模型以便在scikit-learn中使用,以及如何使用網格搜索。如何網格搜索常見的神經網絡參數,如學習速率、 dropout 率、epochs 和神經元數量。如何設計自己的超參數優化實驗。
概述
本文主要想為大家介紹如何使用scikit-learn網格搜索功能,并給出一套代碼實例。你可以將代碼復制粘貼到自己的項目中,作為項目起始。
下文所涉及的議題列表:
如何在scikit-learn模型中使用Keras。如何在scikit-learn模型中使用網格搜索。如何調優批尺寸和訓練epochs。如何調優優化算法。如何調優學習率和動量因子。如何確定網絡權值初始值。如何選擇神經元激活函數。如何調優Dropout正則化。如何確定隱藏層中的神經元的數量。
如何在scikit-learn模型中使用Keras
通過用KerasClassifier或KerasRegressor類包裝Keras模型,可將其用于scikit-learn。
要使用這些包裝,必須定義一個函數,以便按順序模式創建并返回Keras,然后當構建KerasClassifier類時,把該函數傳遞給build_fn參數。
例如:
defcreate_model():... returnmodel model = KerasClassifier(build_fn=create_model)
KerasClassifier類的構建器為可以采取默認參數,并將其被傳遞給model.fit()的調用函數,比如 epochs數目和批尺寸(batch size)。
例如:
defcreate_model():... returnmodel model = KerasClassifier(build_fn=create_model, nb_epoch=10)
KerasClassifier類的構造也可以使用新的參數,使之能夠傳遞給自定義的create_model()函數。這些新的參數,也必須由使用默認參數的 create_model() 函數的簽名定義。
例如:
defcreate_model(dropout_rate=0.0):... returnmodel model = KerasClassifier(build_fn=create_model, dropout_rate=0.2)
您可以在Keras API文檔中,了解到更多關于scikit-learn包裝器的知識。
如何在scikit-learn模型中使用網格搜索
網格搜索(grid search)是一項模型超參數優化技術。
在scikit-learn中,該技術由GridSearchCV類提供。
當構造該類時,你必須提供超參數字典,以便用來評價param_grid參數。這是模型參數名稱和大量列值的示意圖。
默認情況下,精確度是優化的核心,但其他核心可指定用于GridSearchCV構造函數的score參數。
默認情況下,網格搜索只使用一個線程。在GridSearchCV構造函數中,通過將 n_jobs參數設置為-1,則進程將使用計算機上的所有內核。這取決于你的Keras后端,并可能干擾主神經網絡的訓練過程。
當構造并評估一個模型中各個參數的組合時,GridSearchCV會起作用。使用交叉驗證評估每個單個模型,且默認使用3層交叉驗證,盡管通過將cv參數指定給 GridSearchCV構造函數時,有可能將其覆蓋。
下面是定義一個簡單的網格搜索示例:
param_grid = dict(nb_epochs=[10,20,30])grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)grid_result = grid.fit(X, Y)
一旦完成,你可以訪問網格搜索的輸出,該輸出來自結果對象,由grid.fit()返回。best_score_成員提供優化過程期間觀察到的最好的評分, best_params_描述了已取得最佳結果的參數的組合。
您可以在scikit-learn API文檔中了解更多關于GridSearchCV類的知識。
問題描述
現在我們知道了如何使用scikit-learn 的Keras模型,如何使用scikit-learn 的網格搜索。現在一起看看下面的例子。
所有的例子都將在一個小型的標準機器學習數據集上來演示,該數據集被稱為Pima Indians onset of diabetes 分類數據集。該小型數據集包括了所有容易工作的數值屬性。
下載數據集,并把它放置在你目前工作目錄下,命名為:pima-indians-diabetes.csv。
當我們按照本文中的例子進行,能夠獲得最佳參數。因為參數可相互影響,所以這不是網格搜索的最佳方法,但出于演示目的,它是很好的方法。
注意并行化網格搜索
所有示例的配置為了實現并行化(n_jobs=-1)。
如果顯示像下面這樣的錯誤:
INFO (theano.gof.compilelock): Waiting forexisting lock by process '55614'(I am process '55613') INFO (theano.gof.compilelock): To manually release the lock, delete ...
結束進程,并修改代碼,以便不并行地執行網格搜索,設置n_jobs=1。
如何調優批尺寸和訓練epochs
在第一個簡單的例子中,當調整網絡時,我們著眼于調整批尺寸和訓練epochs。
迭代梯度下降的批尺寸大小是權重更新之前顯示給網絡的模式數量。它也是在網絡訓練的優選法,定義一次讀取的模式數并保持在內存中。
訓練epochs是訓練期間整個訓練數據集顯示給網絡的次數。有些網絡對批尺寸大小敏感,如LSTM復發性神經網絡和卷積神經網絡。
在這里,我們將以20的步長,從10到100逐步評估不同的微型批尺寸。
完整代碼如下:
# Use scikit-learn to grid search the batch size and epochsimportnumpy fromsklearn.grid_search importGridSearchCV fromkeras.models importSequential fromkeras.layers importDense fromkeras.wrappers.scikit_learn importKerasClassifier # Function to create model, required for KerasClassifierdefcreate_model():# create modelmodel = Sequential() model.add(Dense(12, input_dim=8, activation='relu')) model.add(Dense(1, activation='sigmoid')) # Compile modelmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) returnmodel # fix random seed for reproducibilityseed = 7numpy.random.seed(seed) # load datasetdataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",") # split into input (X) and output (Y) variablesX = dataset[:,0:8] Y = dataset[:,8] # create modelmodel = KerasClassifier(build_fn=create_model, verbose=0) # define the grid search parametersbatch_size = [10, 20, 40, 60, 80, 100] epochs = [10, 50, 100] param_grid = dict(batch_size=batch_size, nb_epoch=epochs) grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1) grid_result = grid.fit(X, Y) # summarize resultsprint("Best: %f using %s"% (grid_result.best_score_, grid_result.best_params_)) forparams, mean_score, scores ingrid_result.grid_scores_: print("%f (%f) with: %r"% (scores.mean(), scores.std(), params))
運行之后輸出如下:
Best: 0.686198using{'nb_epoch': 100, 'batch_size': 20} 0.348958(0.024774) with: {'nb_epoch': 10, 'batch_size': 10} 0.348958(0.024774) with: {'nb_epoch': 50, 'batch_size': 10} 0.466146(0.149269) with: {'nb_epoch': 100, 'batch_size': 10} 0.647135(0.021236) with: {'nb_epoch': 10, 'batch_size': 20} 0.660156(0.014616) with: {'nb_epoch': 50, 'batch_size': 20} 0.686198(0.024774) with: {'nb_epoch': 100, 'batch_size': 20} 0.489583(0.075566) with: {'nb_epoch': 10, 'batch_size': 40} 0.652344(0.019918) with: {'nb_epoch': 50, 'batch_size': 40} 0.654948(0.027866) with: {'nb_epoch': 100, 'batch_size': 40} 0.518229(0.032264) with: {'nb_epoch': 10, 'batch_size': 60} 0.605469(0.052213) with: {'nb_epoch': 50, 'batch_size': 60} 0.665365(0.004872) with: {'nb_epoch': 100, 'batch_size': 60} 0.537760(0.143537) with: {'nb_epoch': 10, 'batch_size': 80} 0.591146(0.094954) with: {'nb_epoch': 50, 'batch_size': 80} 0.658854(0.054904) with: {'nb_epoch': 100, 'batch_size': 80} 0.402344(0.107735) with: {'nb_epoch': 10, 'batch_size': 100} 0.652344(0.033299) with: {'nb_epoch': 50, 'batch_size': 100} 0.542969(0.157934) with: {'nb_epoch': 100, 'batch_size': 100}
我們可以看到,批尺寸為20、100 epochs能夠獲得最好的結果,精確度約68%。
如何調優訓練優化算法
Keras提供了一套最先進的不同的優化算法。
在這個例子中,我們調整用來訓練網絡的優化算法,每個都用默認參數。
這個例子有點奇怪,因為往往你會先選擇一種方法,而不是將重點放在調整問題參數上(參見下一個示例)。
在這里,我們將評估Keras API支持的整套優化算法。
完整代碼如下:
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%