2019年8月27日 星期二

[ ML 文章收集 ] Ch9 - 使用 Scikit-Learn 調用 Keras 的模型

Source From Here 
Preface 
scikit-learn 是最受歡迎的 Python 的機器學習庫本章我們將使用 scikit-learn 調用 Keras 生成的模型. 本章將: 
* 使用 scikit-learn 封裝 Keras 的模型
* 使用 scikit-learn 對 Keras 的模型進行交叉驗證
* 使用 scikit-learn,利用網格搜索調整 Keras 模型的 Hyperparameter


Introduction 
Keras 在深度學習很受歡迎,但是只能做深度學習:Keras 是最小化的深度學習庫,目標在於快速搭建深度學習模型基於 SciPy 的 scikit-learn,數值運算效率很高,適用於普遍的機器學習任務,提供很多機器學習工具,包括但不限於: 
* 使用 K-Fold Cross validation
* Grid Search for hyperparameter

Keras 為 scikit-learn 了封裝 KerasClassifier
keras.wrappers.scikit_learn.KerasClassifier(build_fn=None, **sk_params): which implements the Scikit-Learn classifier interface,
keras.wrappers.scikit_learn.KerasRegressor(build_fn=None, **sk_params): which implements the Scikit-Learn regressor interface.


使用 Cross Validation 驗證深度學習模型 
Keras 的 KerasClassifier 與 KerasRegressor 兩個類接受 build_fn 參數,傳入函數用以建立模型; 接著我們加入 epochs=150 與 batch_size=10 這兩個參數:這兩個參數會傳入模型的 fit()。方法我們用 scikit-learn 的 StratifiedKFold 類進行 10-Fold Cross validation,測試模型在未知數據的性能,使用並 cross_val_score() 函數檢測模型,打印結果: 
train.py 
  1. #!/usr/bin/env python  
  2. # MLP for Pima Indians Dataset with 10-fold cross validation via sklearn  
  3. from keras.models import Sequential  
  4. from keras.layers import Dense  
  5. from keras.wrappers.scikit_learn import KerasClassifier  
  6. from sklearn.model_selection import StratifiedKFold  
  7. from sklearn.model_selection import cross_val_score  
  8. import numpy  
  9. import pandas  
  10. # Function to create model, required for KerasClassifier  
  11. def create_model():  
  12.     # create model  
  13.     model = Sequential()  
  14.     model.add(Dense(12, input_dim=8, init='uniform', activation='relu'))  
  15.     model.add(Dense(8, init='uniform', activation='relu'))  
  16.     model.add(Dense(1, init='uniform', activation='sigmoid'))  
  17.     # Compile model  
  18.     model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])  
  19.     return model  
  20.   
  21. # fix random seed for reproducibility  
  22. seed = 7  
  23. numpy.random.seed(seed)  
  24.   
  25. # load pima indians dataset  
  26. dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")  
  27.   
  28. # split into input (X) and output (Y) variables  
  29. X = dataset[:,0:8]  
  30. Y = dataset[:,8]  
  31.   
  32. # create model  
  33. model = KerasClassifier(build_fn=create_model, epochs=150, batch_size=10)  
  34.   
  35. # evaluate using 10-fold cross validation  
  36. kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed)  
  37. results = cross_val_score(model, X, Y, cv=kfold)  
  38. print(results.mean())  
Notes. The dataset "pima-indians-diabetes.csv" can be downloaded here

每輪訓練會輸出一次結果,加上最終的平均性能: 
...
Epoch 146/150
692/692 [==============================] - 0s 67us/step - loss: 0.4750 - acc: 0.7717
Epoch 147/150
692/692 [==============================] - 0s 66us/step - loss: 0.4763 - acc: 0.7803
Epoch 148/150
692/692 [==============================] - 0s 66us/step - loss: 0.4776 - acc: 0.7688
Epoch 149/150
692/692 [==============================] - 0s 66us/step - loss: 0.4773 - acc: 0.7673
Epoch 150/150
692/692 [==============================] - 0s 66us/step - loss: 0.4774 - acc: 0.7702
76/76 [==============================] - 0s 2ms/step
0.7408578287970505

比起手工測試,使用 scikit-learn 容易的多。 

使用 GridSearch 調整深度學習模型的參數 
使用 scikit-learn 封裝 Keras 的模型十分簡單, 進一步想:我們可以給 fit() 方法傳入參數,KerasClassifier 的 build_fn 方法也可以傳入參數可以利用這點進一步調整模型。我們可以用 GridSearch 測試不同參數的性能:create_model() 函數可以傳入optimizer:init 參數,雖然都有默認值, 但我們可以用不同的優化算法和初始權優化網絡. 具體來說, 我們希望搜索: 
* 優化算法:搜索權重的方法
* 初始權重:初始化不同的網絡
* 訓練次數:對模型訓練的次數
* 批次大小:每次訓練的數據量

所有的參數組成一個字典,傳入 scikit-learn 的 GridSearchCV 類GridSearchCV 類 會對每組參數(2×3×3×3)進行訓練,進行 3-Fold Cross validation. 這樣做的計算量巨大! 耗時巨長如果模型小還可以取一部分數據試試看,因為這裡的 數據集 與 網絡 都不大(1000 個 數據內,9個參數)所以可以在可接受時間下輸出最好的參數和模型,以及平均值: 
train_gs.py 
  1. #!/usr/bin/env python  
  2. # MLP for Pima Indians Dataset with grid search via sklearn  
  3. from keras.models import Sequential  
  4. from keras.layers import Dense  
  5. from keras.wrappers.scikit_learn import KerasClassifier  
  6. from sklearn.model_selection import GridSearchCV  
  7. import numpy  
  8. import pandas  
  9.   
  10. # Function to create model, required for KerasClassifier  
  11. def create_model(optimizer='rmsprop', init='glorot_uniform'):  
  12.     # create model  
  13.     model = Sequential()  
  14.     model.add(Dense(12, input_dim=8, init=init, activation='relu'))  
  15.     model.add(Dense(8, init=init, activation='relu'))  
  16.     model.add(Dense(1, init=init, activation='sigmoid'))  
  17.   
  18.     # Compile model  
  19.     model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])  
  20.     return model  
  21.   
  22. # fix random seed for reproducibility  
  23. seed = 7  
  24. numpy.random.seed(seed)  
  25.   
  26. # load pima indians dataset  
  27. dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")  
  28.   
  29. # split into input (X) and output (Y) variables  
  30. X = dataset[:,0:8]  
  31. Y = dataset[:,8]  
  32.   
  33. # create model  
  34. model = KerasClassifier(build_fn=create_model)  
  35.   
  36. # grid search epochs, batch size and optimizer  
  37. optimizers = ['rmsprop''adam']  
  38. init = ['glorot_uniform''normal''uniform']  
  39. epochs = numpy.array([50100150])  
  40. batches = numpy.array([51020])  
  41. param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches, init=init)  
  42. grid = GridSearchCV(estimator=model, param_grid=param_grid)  
  43. grid_result = grid.fit(X, Y)  
  44.   
  45. # summarize results  
  46. print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))  
  47.   
  48. best_model = grid.best_estimator_  
  49. print('Best model={}'.format(best_model.__class__))  
用 CPU 差不多要 5分鐘,結果如下我們發現使用均勻分佈初始化。RMSPro 優化算法,150 epochs,batch size 為 5 時效果最好,正確率約 75%: 

Supplement 
Keras Doc - Wrappers for the Scikit-Learn API 
Ch10 - 多類花朵分類 (iris dataset) 
ML CheatSheet - Optimizer

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...