Keras with scikit-learnのメモ

KerasはTensorflow/Theanoを使って良くあるDeep Learningアルゴリズムのパタンを効率的に実装するライブラリだけど、機械学習と言えばデータ前処理やCross-Validation,パラメタ探索とか他にも共通してやることがたくさんある。そんな機械学習共通のライブラリと言えばscikit-learnでしょ、ということで、Kerasはscikit-learnへのラッパーも提供している。

使い方の概要

  • sklearnのCVやグリッドサーチなどは、分類器(Classifier)、回帰器(Regressor)ともにEstimatorクラスのオブジェクトを受け取ることを想定している。
  • kerasはそれらのEstimatorを返すラッパーを提供していて、それがKerasClassifierとKerasRegressor。
  • KerasClassifer(Regressor)はモデルを返す関数を引数として与える必要がある。それを何か(gen_modelなど)作って渡すだけで、後はscikit-learnのEstimatorと同じように扱ってくれる。
  • KerassRegressorに渡すbuild_fnが引数を取る場合、build_fnの後ろにそのままキーワード引数として与えてあげれば良い。epochsとかはデフォルトなのかな?(例 KerasRegressor(build_fn=gen_model, arg1=xxx, arg2=yyy, epochs=...)

kFold-CVをする場合

# データセットはpima_indians_diabets
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score

# Data preparetion
dataset = numpy.loadtxt("pima_indians_diabetes.csv", delimiter=",")
X = dataset[:, 0:8]
Y = dataset[:, 8]


def gen_model():
    model = Sequential()
    model.add(Dense(12, input_dim=8, activation='relu'))
    model.add(Dense(6, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam',
                  metrics=['accuracy'])
    return model


# KerasClassifier/KerasRegressor can be used as same as scikit_learn estimator.
model = KerasClassifier(build_fn=gen_model, epochs=10, batch_size=10)

# scikit_learn's cross-validation flow
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=1)
results = cross_val_score(model, X, Y, cv=kfold)
print(results.mean())

Grid-Searchする場合

  • 同様にGSも簡単にやってくれる。活性化関数、初期化方式、バッチサイズ, エポック数を探索する場合の例。
import numpy
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV


dataset = numpy.loadtxt("pima_indians_diabetes.csv", delimiter=",")
X = dataset[:, 0:8]
Y = dataset[:, 8]


def create_model(optimizer='rmsprop', init='glorot_uniform'):
    model = Sequential()
    model.add(Dense(12, input_dim=8, kernel_initializer=init, activation='relu'))
    model.add(Dense(8, kernel_initializer=init, activation='relu'))
    model.add(Dense(1, kernel_initializer=init, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer=optimizer,
                  metrics=['accuracy'])
    return model


# KerasClassifier/KerasRegressor can be used as same as scikit_learn estimator.
model = KerasClassifier(build_fn=create_model)

# Grid Search parameters (epochs, batch size and optimizer)
optimizers = ['rmsprop', 'adam']
init = ['glorot_uniform', 'normal', 'uniform']
epochs = [10, 20, 30]
batches = [5, 10, 20]
param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches,
                  init=init)
grid = GridSearchCV(estimator=model, param_grid=param_grid)
grid_result = grid.fit(X, Y)

# summarize results
print("Best parameter set: {}".format(grid_result.best_params_))