💿 Data/이모저모

[딥러닝]하이퍼 파라미터 튜닝(sklearn의 RandomizedSearchCV, keras_tuner의 RandomSearch)

Jayden1116 2022. 3. 1. 16:04

RandomSearch를 이용한 하이퍼 파라미터 튜닝

0. 데이터 불러오기 및 Normalization

# 데이터 불러오기
from tensorflow.keras.datasets import mnist

(X_train, y_train), (X_test, y_test) = mnist.load_data()

# input 및 target 데이터 확인
X_train.shape
set(y_train)

# Normalization
X_train = X_train / 255.
X_test = X_test / 255.

1. 모델링

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Dropout

model = Sequential()

model.add(Flatten(input_shape=(28, 28)))
model.add(Dense(128, activation='relu'))
model.add(Dense(64, 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=30, batch_size=32, validation_data=(X_test, y_test))

# 베이스모델 테스트
model.evaluate(X_test, y_test, verbose=2)

image

2. 하이퍼 파라미터 튜닝

2-1. sklearn의 RandomizedSearchCV

from tensorflow.keras.regularizers import L1, L2
from sklearn.model_selection import RandomizedSearchCV
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier

# 모델 설계
def build_model_rscv(nodes, L1_values, L2_values, dropout_values):

    model = Sequential()

    model.add(Flatten(input_shape=(28, 28)))
    model.add(Dense(nodes, activation='relu',
                    kernel_regularizer=L2(L2_values)))
    model.add(Dense(nodes, activation='relu',
                    activity_regularizer=L1(L1_values)))
    model.add(Dropout(dropout_values))
    model.add(Dense(10, activation='softmax'))

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

    return model

# KerasClassifier로 wrapping
temp_rscv = KerasClassifier(build_fn=build_model_rscv, verbose=0)

# params 설정 및 RandomizedSearchCV
import random

nodes=[random.randint(32, 128) for n in range(5)]
L1_values=[random.uniform(0, 0.000001) for n in range(5)]
L2_values=[random.uniform(0, 0.000001) for n in range(5)]
dropout_values=[random.uniform(0, 1) for n in range(5)]
batch_sizes=[random.randint(32, 64) for n in range(5)]
epochs=[random.choice(range(30, 160, 10)) for n in range(5)]

params = dict(nodes=nodes,
              L1_values=L1_values,
              L2_values=L2_values,
              dropout_values=dropout_values,
              batch_size=batch_sizes,
              epochs=epochs
              )

model_best = RandomizedSearchCV(estimator=temp_rscv,
                                param_distributions=params,
                                n_iter=10,
                                cv=3,
                                scoring='accuracy',
                                verbose=1,
                                n_jobs=-1
                                )

model_best.fit(X_train, y_train, validation_data=(X_test, y_test))

import pandas as pd

rs = pd.DataFrame(model_best.cv_results_).sort_values(by='rank_test_score').head()
rs.T

image

image

2-2. keras_tuner의 RandomSearch

from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense, Flatten, Dropout

!pip install -U keras-tuner
import kerastuner as kt

# 모델링(은닉층의 노드수에만 튜닝해보았습니다.)
def model_builder(hp):
    model = Sequential()

    hp_units = hp.Int('units', min_value=32, max_value=512, step=64) # python의 range와 비슷한 개념

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

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

    return model

# 튜너 세팅
tuner = kt.RandomSearch(
    hypermodel=model_builder,
    objective='val_loss',
    max_trials=5
    )  

# 최적의 하이퍼 파라미터값 서칭
tuner.search(X_train, y_train, epochs=10, validation_data=(X_test, y_test))

best_hps = tuner.get_best_hyperparameters(num_trials = 1)[0]

model = tuner.hypermodel.build(best_hps)
model.fit(X_train, y_train, epochs = 10, validation_data = (X_test, y_test))

image

image

image

이상입니다. 감사합니다. :)