上一篇我們作了一些實驗,對單一參數作各種數值的比較,但是,如果同時使用多個參數作各種組合的比較,那就需要撰寫迴圈了,讓每一種組合依序執行,再加上 Cross Validation,執行中應該可以先出去辦事,再回來看結果了,幸好 Scikit-Learn 提供 GridSearchCV 函數,支援同步執行,可大量節省執行時間,但前提是你的機器要夠強,多核心、記憶體不會爆掉。
GridSearchCV 函數會自動作Cross Validation,並且統計準確率的平均數/標準差,幫我們找出最佳參數組合,我們現在就整合Tensorflow與GridSearchCV,試作一範例說明如下,檔案名稱為04_06_GridSearchCV.ipynb。
重要的程式片段如下:
# 建立模型
def create_model(learn_rate=0.01, neurons=128):
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(neurons, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
# 設定優化器(optimizer)、損失函數(loss)、效能衡量指標(metrics)的類別
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
from sklearn.model_selection import GridSearchCV
# 建立模型,並以 KerasClassifier 包起來,提供 GridSearchCV 使用
model = tf.keras.wrappers.scikit_learn.KerasClassifier(build_fn=create_model, epochs=5, verbose=1)
# 定義參數各種組合
neurons = [16, 128, 512]
learn_rate = [0.1, 0.01, 0.001]
param_grid = dict(learn_rate=learn_rate, neurons=neurons)
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=1)
# 訓練
grid_result = grid.fit(x_train_norm, y_train)
# 評估,打分數
print(f"最佳準確率: {grid_result.best_score_},最佳參數組合:{grid_result.best_params_}")
# 取得 cross validation 的平均準確率及標準差
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print(f"平均準確率: {mean}, 標準差: {stdev}, 參數組合: {param}")
評估結果如下:
如果時間足夠的話,可以納入更多的超參數並列舉更多的組合,透過以上的方法,我們就可以得到最佳模型了。
下一篇我們繼續介紹 Keras 更多的語法與相關的應用,Happy coding。
本篇範例包括04_06_GridSearchCV.ipynb,可自【這裡】下載。