본문 바로가기
Deep Learning/Hands On Machine Learning

10.3 신경망 하이퍼 파라미터 튜닝하기

by 대소기 2021. 9. 24.

scikit learn wrapping함수 만들기

import tensorflow as tf
from tensorflow import keras

fashion_mnist=keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()

#validation set 생성 및 픽셀 값을 0~1사이의 값으로 정규화
X_valid, X_train = X_train_full[:5000] / 255., X_train_full[5000:] / 255.
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
X_test = X_test/255.

class_names=['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
             'Sandal', 'Shirt', 'Sneaker','Bag', 'Ankle boot']
  • 저번 장에 이어 이번 장에서도 fashion mnist 데이터를 이용한다.

#단변량 회귀를 위한 NN
def build_model(n_hidden=1, n_neurons=30, learning_rate=3e-3, input_shape=[28,28]):
  model=keras.models.Sequential()
  model.add(keras.layers.InputLayer(input_shape=input_shape))
  for layer in range(n_hidden):
    model.add(keras.layers.Dense(n_neurons, activation='relu'))
  model.add(keras.layers.Dense(1))
  optimizer=keras.optimizers.SGD(learning_rate=learning_rate)
  model.compile(loss='mse', optimizer=optimizer)
  return model
  • 하이퍼 파라미터 튜닝을 위해서는 GridSearchCV나 RandomizedSearchCV 등을 사용해야 하고 이 기능들은 scikit-learn 라이브러리에 잘 구현되어 있다.
  • 때문에 keras 모델을 scikit-learn 모델처럼 사용하기 위해 랩핑을 해줘야 한다.
#keras wrapping
keras_reg=keras.wrappers.scikit_learn.KerasRegressor(build_model)

그리드 서치 vs 랜덤 서치

그리드 서치(Grid Search)

  • 탐색 범위를 일일히 지정해줘야 함.
  • 지정해준 모든 경우의 수를 탐색해야하기 때문에 다수의 하이퍼 파라미터를 튜닝하는 경우에 시간이 오래걸림
  • gloabl optimum이 아닌 local opitmum(지정해 둔 범위만 탐색하기 때문에 지정한 범위 내의 최적해밖에 찾지 못함)

랜덤 서치(Randomized Search)

  • 최적 해에 대한 아무런 정보가 없는 초기에 활용하기 좋음
  • random하게 하이퍼 파라미터를 탐색하기 때문에 random seed에 따라 다른 결과를 도출함.
  • 하이퍼 파라미터 탐색 범위를 지정해주는 것이 아니라, 탐색 횟수를 지정하기 때문에 빠르게 탐색이 끝난다.
  • 때문에 많은 양의 하이퍼 파라미터를 탐색할 때 사용하기 용이하다.
  • 첫 번째 탐색에는 넓은 범위의 파라미터 값을 탐색하고, 첫 번째 탐색에서 찾은 최적 파라미터 값 중심으로 더 좁은 범위를 탐색해 나간다.

랜덤 서치 적용

import numpy as np
from scipy.stats import reciprocal
from sklearn.model_selection import RandomizedSearchCV

param_distribs={
    'n_hidden' : [0, 1, 2, 3],
    'n_neurons' : np.arange(1, 100),
    'learning_rate' : reciprocal(3e-4, 3e-2),
}

rnd_search_cv=RandomizedSearchCV(keras_reg, param_distribs, n_iter=10, cv=3)
rnd_search_cv.fit(X_train, y_train, epochs=100,
                  validation_data=(X_valid, y_valid),
                  callbacks=[keras.callbacks.EarlyStopping(patience=10)])

랜덤 서치 결과

rnd_search_cv.best_params_
  • 위 코드로 랜덤 서치를 통해 도출한 최적 파라미터를 찾을 수 있다.
rnd_search_cv.best_score_
  • best score에 대한 값은 음수의 MSE 값이다.
model=rnd_search_cv.best_estimator_.model
  • 위와 같이 최적 파라미터 값을 모델에 적용할 수 있다.

그 외의 하이퍼 파라미터 탐색 방법(파이썬 라이브러리)

  • Hyperopt : 모든 종류의 복잡한 탐색 공간에 대해 사용 가능(연속적인 값, 이산적인 값)
  • Hyperas, Kopt, Talos : Hyperas, Kopt는 Hyperopt 기반이다. 케라스 모델을 위한 하이퍼파라미터 최적화 라이브러리
  • Keras Tuner : 구글이 개발한 케라스 하이퍼 파라미터 최적화 라이브러리
  • Scikit-Optimize(skopt) : 범용 최적화 라이브러리. BayesSearchCV 지원
  • Spearmint : 베이즈 최적화 라이브러리
  • Hyperband : Lisha Li의 'Hyperband' 논문을 기반으로 구축된 라이브러리
  • Sklearn - Deep : evolutionary algorithm 기반의 하이퍼 파라미터 최적화 라이브러리

10.3.1 은닉층 개수

  • 이론적으로는 은닉층이 하나인 다층 퍼셉트론이더라도 뉴런 개수가 충분하면 복잡한 함수도 모델링 가능
  • 하지만, 은닉층을 하나 두는 것보다 여러개 두는 것이 파라미터 효율성이 좋기 때문에(더 적은 수의 뉴런을 훈련시키기 때문) 여러개의 은닉층을 사용한다.

은닉층의 계층 구조와 전이학습

  • 저수준의 구조 : 아래쪽 은닉층
  • 중간 수준의 구조 : 중간 은닉층
  • 고수준 구조 : 가장 위쪽 은닉층과 출력층
  • 전이학습(Transfer Learning) : 이러한 구분이 되어있기 때문에 기존에 훈련된 신경망의 저수준 구조를 가져와 새로운 신경망에 활용하는 등의 작업이 가능하다.

10.3.2 은닉층의 뉴런 개수

  • 은닉층의 뉴런 개수는 깔때기처럼 점점 줄여 나가는 구조로 구성하여 저수준의 많은 특성이 고수준으로 합쳐지도록 구성하는 것이 일반적이었으나, 요즘엔 모든 은닉층에 같은 크기를 뉴런을 배치해도 동일하거나 더 나은 성능을 보인다.

Stretch Pants 방식

  • Google의 Vincent Vanhoucke가 주장한 방법론으로, 네트워크를 과대적합 전까지 점점 키워가기보다는 필요한 것 보다 크게 구성한 후 여러가지 규제기법으로 과대적합을 막는것이 적절하다는 주장이다.
  • Stretch Pants 방식을 사용하면 병목층 문제를 방지할 수 있다.

10.3.3 학습률, 배치 크기 그리고 다른 하이퍼 파라미터

학습률(Learning Rate)

  • 최적 학습률 = 최대 학습률(값이 발산하는 학습률)의 절반 정도
  • 매우 낮은 학습률부터 큰 학습률까지 수백 번 반복하여 모델을 훈련시키며 최적 학습률을 찾는다. ex) $10^-5 ~ 10$까지 $exp(log(10^6)/500)$을 500번 반복하여 곱한다.
  • 손실이 최소가 되는 점을 최적 학습률로 간주하고 해당 학습률을 적용한다.

옵티마이저(Optimizer)

  • 11장에서 더 자세히 다룸

배치 크기

  • 큰 배치 크기는 가중치를 1번 갱신하는데 걸리는 시간이 길지만, 전체 데이터를 한번에 학습하기 때문에 최소 오차로 향하는 경로가 안정적이다. 하지만, 오차를 최소화 하는 방향이 작은 배치 크기보다 일관되기 때문에 Global minimum이 아닌 Local minimum에 빠질 위험이 있다.
  • 작은 배치 크기는 최소 오차로 향하는 경로가 불안정하지만, Local minimum에 빠질 가능성이 적다. Global minimum에 도달할 가능성이 큰 배치 크기보다 높기 때문에 일반화 성능이 좋다.

https://optilog.tistory.com/7
https://www.kakaobrain.com/blog/113