Friday, April 26, 2019

Menggunakan GridSearchCV untuk optimasi hyperparameter pada Keras

Salah satu permasalahan pada pembangunan (development) model deep learning adalah mencari hyperparameter optimal. Contohnya sebagai berikut:
  1. Berapa ukuran batch_size optimal: 16, 32, 64 atau 128?
  2. Berapa epoch optimal untuk menjalankan model deep learning: 10, 20, 50 atau 100?
  3. Apa optimizer terbaik untuk deep learning model ini: atam, rmsprop, atau adadelta...?
Dan masih banyak hiperparameter lainnya yang bisa dioptimasi: Dropout, jumlah node, jumlah layer, fungsi aktivasi apa yang digunakan, dan lain-lainnya. Habis waktu kita jika digunakan untuk trial-error mencoba mengganti satu-satu parameter tersebut untuk mencari model terbaik. Salah satu solusi dari permasalahan ini adalah dengan menggunakanGridSearch.

Grid search, sesuai namanya, mencari parameter dalam "grid" yang diberikan. Misalnya jumlah epochs=[10, 20], mana diantara kedua nilai tersebut yang memberikan hasil terbaik. CV, di akhir kata GridSearchCV, merupakan kepanjangan dari cross-validation: validasi silang. Artinya, data kita (input) akan dibagi oleh GridSearchCV ketika menjalankan deep learning menjadi beberapa fold, untuk mengurangi bias. Silahkan baca selengkapnya disini untuk validasi silang ini. By default, GridSearchCV akan membagi satu dataset menjadi porsi 77/33 untuk train/test data. Sehingga dengan 3 fold, kita seperti memiliki 3 dataset seperti di bawah ini.

Pembagian data dengan 3 fold (sumber: http://brettromero.com/data-science-kaggle-walkthrough-creating-model/)

Langsung cus saja ke contoh berikut. Contoh pertama tanpa Grid Seach, dan contoh kedua dengan GridSearchCV untuk mencari parameter optimum dari batchsize dan optimizer. Dataset yang kita gunakan adalah dataset mnist yang umum digunakan untuk pengenalan citra.

Keras tanpa GridSearchCV (manual)
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Flatten, Dropout

# load dataset
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = Sequential()
model.add(Flatten(input_shape=(28, 28)))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=3)
model.evaluate(x_test, y_test)

Hasilnya adalah:
0.97

Keras dengan menggunakan GridSeachCV (automatic)
''' Keras wrapper for sklearn GridSearchCV minimum example
'''

import numpy as np
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Flatten, Dropout
from keras.wrappers.scikit_learn import KerasClassifier

from sklearn.model_selection import GridSearchCV

# load dataset
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

X = np.vstack((x_train, x_test)) 
y = np.hstack((y_train, y_test))

def build_model(optimizer='adam'):
    model = Sequential()
    model.add(Flatten(input_shape=(28, 28)))
    model.add(Dense(512, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(10, activation='softmax'))

    model.compile(optimizer=optimizer,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

    return model
    
batch_size = [32, 256]
optimizer = ['adam', 'rmsprop']

param_grids = dict(batch_size = batch_size, optimizer = optimizer)

model = KerasClassifier(build_fn=build_model, epochs=3, verbose=1)
grid = GridSearchCV(estimator=model, param_grid=param_grids)
result = grid.fit(X, y)

print("Best: {} using {}".format(result.best_score_, result.best_params_))

Hasilsnya adalah sebagai berikut,
Best: 0.9735714285714285 using {'batch_size': 32, 'optimizer': 'adam'}

Tidak berbeda jauh memang untuk contoh kasus MNIST dataset di atas. Namun, bisa berguna untuk data dan model deeplearning lainnya. (Maybe..)
Related Posts Plugin for WordPress, Blogger...