3 분 소요

“핸즈온 머신러닝”의 “10장 케라스를 사용한 인공신경망 소개” 파트를 읽고 공부한 내용을 정리해보았다. 신경망 하이퍼파라미터를 조정하는 방법을 다뤄볼 것이다.

10.3 신경망 하이퍼파라미터

  • 어떤 하이퍼파라미터 조합이 주어진 문제에 최적인지 알 수 있을까?

  • 방법1

    • 많은 하이퍼파라미터 조합을 시도해보고 어떤 것이 검증 세트에서 가장 좋은 점수를 내는지 확인한다.

    • GridSearchCV나 RandomizedSearchCV를 사용해 하이퍼파라미터 공간을 탐색할 수 있다.


# 케라스 모델을 사이킷런 추정기처럼 보이도록 바꾸자
def bulid_model(n_hidden=1, n_neurons=30, learning_rate=3e-3, input_shape=[8]):
  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

코드 설명

  • 주어진 입력 크기, 은닉층 개수, 뉴런 개수로 일변량 회귀를 위한 간단한 Sequential 모델을 만들었다.

  • 지정된 학습률을 사용하는 SGD 옵티마이저로 모델을 컴파일한다.


# KerasRegressor 클래스의 객체를 만들어보자
keras_reg = keras.wrappers.scikit_learn.KerasRegressor(bulid_model)

KerasRegressor

  • build_model() 함수로 만들어진 케라스 모델을 감싸는 간단한 Wrapper다.


# 모델을 훈련, 평가, 예측하기
keras_reg.fit(X_train, y_train, epochs=100,
              validation_data=(X_valid, y_valid),
              callbacks=[keras.callbacks.EarlyStopping(patience=10)])
mse_test = keras_reg.score(X_test, y_test)
X_new = X_test[:3]
y_pred = keras_reg.predict(X_new)

은닉층 개수, 뉴런 개수, 학습률을 이용해 하이퍼파라미터 탐색을 수행해보자

  • 하이퍼파라미터가 많기 때문에 그리드 탐색보다 랜덤 탐색을 수행한다.

  • RandomizedSearchCV

    • k-겹 교차검증을 사용하기 때문에 X_valid와 y_valid를 사용하지 않고, 조기 종료에만 사용한다.

    • 실행이 끝나면 최상의 하이퍼파라미터와 훈련된 케라스 모델을 얻을 수 있다.


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=20, 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_
# 최상의 score
rnd_search_cv.best_score_
# 훈련된 케라스 모델
model.rnd_search_cv.best_estimator_.model
  • 모델을 저장하고 테스트 세트에서 평가한다.

  • 성능이 만족스러우면 상용 환경에 배포할 수 있다.


RandomizedSearchCV 단점

  • 대규모 데이터 셋으로 복잡한 모델을 훈련할 때 탐색할 수 있는 하이퍼파라미터 공간에 제약이 생긴다.


효율적인 탐색 기법

  • 탐색 지역이 좋다고 판명될 때 탐색을 더 수행한다.

  • 하이퍼파라미터 최적화에 사용되는 파이썬 라이브러리

    • Hyperopt: 모든 종류의 탐색공간에 대해 최적화 수행할 수 있다.

    • Hyperas, kopt, Talos: 케라스 모델을 위한 하이퍼파라미터 최적화 라이브러리

    • 케라스 튜너: 사용하기 쉬운 케라스 하이퍼파라미터 최적화 라이브러리

    • Scikit-Optimize(skopt): 범용 최적화 라이브러리

    • Spearmint: 베이즈 최적화 라이브러리

    • Hyperband: 빠른 하이퍼파라미터 튜닝 라이브러리

    • Sklearn-Deap: Evolutionary Algorithm 기반의 하이퍼파라미터 최적화 라이브러리

  • 그러나 요즘 클라우드에서 자동으로 신경망을 구축해주는 시대가 오고 있다…!


10.3.1 은닉층 개수

  • 복잡한 문제에서는 심층 신경망이 얕은 신경망보다 파라미터 효율성이 훨씬 좋다. 훨씬 더 적은 수의 뉴런을 사용하기 때문이다. => 동일한 양의 훈련 데이터에서 더 높은 성능을 낼 수 있다.

  • 계층 구조의 장점 = 전이학습(Transfer Learning)

    • 하위 층을 재사용하여 훈련을 할 수 있다. => 저수준 구조를 학습할 필요가 없고 고수준 구조만 학습하면 된다!
  • 과정

    • 은닉층의 수를 하나에서 늘려가면서 과대적합이 생길 때까지 점진적으로 은닉층의 수를 늘린다.

    • 하지만 이런 네트워크를 처음부터 훈련하는 경우는 드물다 => 비슷한 작업에서 가장 뛰어난 성능을 낸 pretrained된 네트워크 일부를 재사용하는 것이 일반적이다.


10.3.2 은닉층의 뉴런 개수

TIP 일반적으로 층의 뉴런 수보다 층 수를 늘리는 쪽이 이득이 많다!

  • 입력층과 출력층의 뉴런 개수

    • 해당 작업에 필요한 입력과 출력의 형태에 따라 결정된다.
  • 은닉층의 뉴런 개수

    • 일반적으로 각 층의 뉴런을 점점 줄여서 깔때기처럼 구성한다. (저수준의 많은 특성이 고수준의 적은 특성으로 합쳐질 수 있기 때문)

      • ex) layer1: 300, layer2: 200, layer3: 100
    • 하지만 각 층의 뉴런을 동일하게 둔 경우 더 나은 성능을 낼 수 있다. => 튜닝할 하이퍼파라미터가 전체를 통틀어 한 개가 된다.

  • 방법1: 네트워크가 과대적합이 시작되기 전까지 점진적으로 뉴런 수를 늘릴 수 있다.

  • 방법2: 실전에서는 필요한 것보다 더 많은 층과 뉴런을 가진 모델을 선택하고 과대적합이 되지 않도록 조기 종료나 규제 기법을 사용하는 것이 간단하고 효과적이다.

  • => 병목층을 피할 수 있다!


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

학습률

  • 매우 낮은 학습률 ex) 10^(-5) 에서 시작해서 점진적으로 매우 큰 학습률 ex)10 까지 수백 번 반복하여 모델을 훈련하는 것이다.

  • 반복마다 일정한 값을 학습률에 곱한다.

    ex) 10^(-5)부터 10까지 exp(log(10^6)/500)을 500번 반복하여 곱한다.

  • 학습률에 대한 손실을 그래프로 그리면 처음에 손실이 줄어들고 커지는 것이 보인다. (일반적으로 최적의 학습률은 상승점보다 약 10배 낮은 지점이다)

  • 최적의 학습률을 찾았으면 모델을 다시 초기화하고 다시 훈련한다.


옵티마이저

  • 미니배치 경사하강법 보다 더 좋은 옵티마이저를 선택하고 튜닝하는 것도 중요하다. 이 부분은 11장에서 다루도록 한다.


배치 크기

  • 일반적: GPU RAM에 맞는 가장 큰 배치 크기를 사용하자

  • 큰 배치 단점:

    • 실전에서 큰 배치를 사용하면 훈련 초기에 종종 불안정하게 훈련된다.

    • 작은 배치로 훈련된 모델만큼 일반화 성능을 내지 못할 수 있다.

  • 작은 배치 장점

    • 작은 배치가 적은 훈련 시간으로 더 좋은 모델을 만들기 때문

    • ex) 2에서 32까지

  • 학습률 예열(작은 학습률로 훈련을 시작해서 점점 커짐)같은 기법을 사용하면 매우 큰 배치크기를 사용할 수 있다.

    • ex) 8192까지
  • 학습률 예열 기법을 사용해 큰 배치를 시도해보고 훈련이 불안정하거나 최종 성능이 만족스럽지 않으면 작은 배치 크기를 사용하자


활성화 함수

  • 은닉층: 일반적으로 ReLU 활성화 함수가 모든 은닉층에서 좋은 기본값이다.

  • 출력층: 수행하는 작업에 따라 활성화 함수가 달라진다.


반복 횟수

  • 대부분의 경우 훈련 반복 횟수는 튜닝할 필요가 없다.

  • 대신 조기 종료를 사용한다.

지금까지 신경망 하이퍼파라미터를 조정하여 모델의 성능을 높이는 방법에 대해 알아보았다. 다음 장에서는 매우 깊은 네트워크를 훈련하는 방법을 다뤄볼 것이다.

댓글남기기