[AI/Hands-on ML] - [핸즈온 머신러닝] 10장 - 케라스를 사용한 인공 신경망 2 (케라스로 딥러닝하기)
10. 3 신경망 하이퍼파라미터 튜닝하기
신경망의 유연성은 조정할 하이퍼파라미터가 많다는 단점을 가짐
주어진 문제에 최적인 하이퍼파라미터 조합을 찾는 방법
- 많은 하이퍼파라미터 조합을 시도해보고 어떤 것이 검증 세트에서 가장 좋은 점수를 내는지 확인
- GridSearchCV 나 RandomizedSearchCV를 사용해 하이퍼파라미터 공간 탐색
-> 이렇게 하려면 케라스 모델을 사키잇런 추정기처럼 보이도록 바꾸어야함
일련의 하이퍼파라미터로 케라스 모델을 만들고 컴파일하는 함수 만들기
def build_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(lr=learning_rate)
model.compile(loss="mse", optimizer=optimizer)
return model
- 입력 크기와 은닉층 개수, 뉴런 개수로 단변량 회귀를 위한 간단한 Sequential 모델을 만듦
- 지정된 학습률을 사용하는 SGD 옵티마이저로 모델을 컴파일
keras_reg = keras.wrappers.scikit_learn.KerasRegressor(build_model)
- build_model() 함수로 만들어진 케라스 모델을 감싸는 래퍼
- 객체 생성시 하이퍼파라미터를 지정하지 않았으므로 기본 값 사용
-> 사이킷런 회귀 추정기처럼 이 객체를 사용할 수 있음
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)
y_pred = keras_reg.predict(X_new)
- fit() 메서드에 지정한 모든 매개변수는 케라스 모델로 전달 됨
- 사이킷런은 손실이 아니라 점수를 계산하므로 출력 점수는 음수의 MSE
하이퍼파라미터 탐색
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) .tolist(),
"learning_rate": reciprocal(3e-4, 3e-2) .rvs(1000).tolist(),
}
rnd_search_cv = RandomizedSearchCV(keras_reg, param_distribs, n_iter=10, cv=3, verbose=2)
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_
=> {'n_neurons': 74, 'n_hidden': 3, 'learning_rate': 0.005803602934201024}
rnd_search_cv.best_score_
=> -0.32039451599121094
rnd_search_cv.best_estimator_
- 이 후 모델을 저장하고 테스트 세트에서 평가하고, 만족스럽다면 상용 환경에 배포
랜덤 탐색은 간단한 문제에서 잘 동작하지만 훈련에 시간이 많이 걸리면 탐색할 수 있는 하이퍼파라미터 공간에 제약이 생김
하히어파라미터 공간 탐색 기법
탐색 지역이 좋다고 판명될 때 더 탐색을 수행하는 아이디어
- Hyperopt
- Hyperas, kopt, Talos
- 케라스 튜너
- Scikit-Optimizer(skopt)
- Spearmint
- Hyperband
- Sklearn-Deap
AutoML
ai.googleblog.com/2018/03/using-evolutionary-automl-to-discover.html
심층 신경 진화 기법
eng.uber.com/deep-neuroevolution/
10. 3. 1 은닉층 개수
- 은닉층이 하나인 다층 퍼셉트론이더라도 뉴런 개수가 충분하면 복잡한 함수도 모델링할 수 있지만,
- 복잡한 문제에서는 심층 신경망이 얕은 신경망보다 파라미터 효율성이 좋음
- 심층 신경망은 복잡한 함수를 모델링하는 데 얕은 신경망보다 훨씬 적은 수의 뉴런을 사용하므로 동일한 양의 훈련 데이터에서 더 높은 성능을 냄
실제 데이터는 계층 구조를 가진 경우가 많으므로, 심층 신경망은 이런 경우에 유리
- 아래쪽 은닉층은 저수준의 구조를 모델링하고 (ex. 여러 방향이나 모양의 선)
- 중간 은닉층은 저수준의 구조를 연결해 중간 수준의 구조를 모델링 (ex. 사각형, 원)
- 가장 위쪽 은닉층과 출력층은 중간 수준의 구조를 연결해 고수준의 구조를 모델링 (ex. 얼굴)
계층 구조는 심층 신경망이 좋은 솔루션으로 수렴하게끔 도와줄 뿐만 아니라 새로운 데이터에 일반화되는 능력도 향상시켜줌
- 사진에서 얼굴을 인식하는 모델을 훈련한 후 헤어스타일을 인식하는 신경망을 새로 훈련하면 첫 번째 네트워크의 하위 층을 재사용하여 훈련을 시작할 수 있음
- 새로운 신경망에서 초기화하는 대신 첫 번째 신경망의 층에 있는 가중치와 편향값으로 초기화 가능
- 저수준 구조를 학습하지 않아도 됨, 헤어스타일 같은 고수준 구조만 학습하면 됨
=> 이를 전이 학습이라고 함
대규모 이미지 분류나 음성인식 같은 매우 복잡한 작업에서는 일반적으로 수십 개 층의 네트워크가 필요함
- 훈련 데이터도 아주 많이 필요함
- 이런 네트워크를 처음부터 훈련하는 경우는 드뭄
- 비슷한 작업에서 뛰어난 성능을 낸 미리 훈련된 네트워크 일부를 재사용 함
10. 3. 2 은닉층의 뉴런 개수
입력층과 출력층의 뉴런 개수는 해당 작업에 필요한 입력과 출력의 형태에 따라 결정됨
- MNIST는 28*28 개의 입력 뉴런과 10개의 출력 뉴런이 필요함
은닉층의 구성 방식
일반적으로 각 층의 뉴런을 점점 줄여서 깔때기처럼 구성
- 저수준의 많은 특성이 고수준의 적은 특성으로 합쳐질 수 있기 때문
- 예를들어 MNIST 신경망은 첫 번째 300개, 두 번째 200개, 세 번째는 100개의 뉴런으로 구성된 세 개의 은닉층을 가짐
=> 이 구성은 요즘 일반적이지 않음
- 대부분의 경우 모든 은닉층에 같은 크기를 사용해도 동일하거나 더 나은 성능을 냄
- 튜닝할 하이퍼파라미터가 층마다 한 개씩이 아니라 전체 통틀어 한 개가 됨
- 데이터셋에 따라 다르지만 다른 은닉층보다 첫 번째 은닉층을 크게 하는 것이 도움이 됨
뉴런 개수
층의 개수와 마찬가지로 네트워크가 과대적합되기 전까지 점진적으로 뉴런 수를 늘릴 수 있음
- 하지만 실제로는 필요한 것보다 더 많은 층과 뉴런을 가진 모델을 선택하고 그 후 과대적합 되지 않도록 조기 종료나 규제를 사용하는 것이 간단하고 효과적임
-
모델에서 문제를 일으키는 병목층을 피할 수 있음
-
하지만 한 층의 뉴런 수가 너무 적으면 입력에 있는 유용한 정보를 모두 유지하기 위한 표현 능력을 가지지 못함
-
EX. 뉴런 두 개를 가진 층은 2D 데이터만 출력할 수 있음 (3D 데이터 처리시 일부 정보를 잃음)
-
-> 네트워크의 나머지 층과 상관없이 이 정보는 복원되지 않음
-
※ 일반적으로 층의 뉴런 수보다 층 수를 늘리는 쪽이 이득이 많음
10. 3. 3 학습률, 배치 크기, 그리고 다른 하이퍼파라미터
은닉층과 뉴런 개수 외에, 가장 중요한 하이퍼파라미터 일부와 조정 방법
학습률
- 가장 중요한 하이퍼파라미터
- 일반적인 최적의 학습률은 최대 학습률 (훈련 알고리즘이 발산하는 학습률)의 절반 정도
- 좋은 학습률을 찾는 하나의 방법은 매우 낮은 학습률(ex. 10^-5)에서 시작해 점진적으로 매우 큰 학습률(ex. 10) 까지 수백 번 반복하며 모델을 훈련하는 것
- 반복마다 일정한 값을 학습률에 곱함
- 학습률에 대한 손실을 그래프로 그리면 처음에 손실이 줄어드는 것이 보임
- 하지만 잠시 후 학습률이 커지면 손실이 다시 커짐
- 최적의 학습률은 손실이 다시 상승하는 지점보다 조금 아래에 있을 것 (일반적으로 상승점보다 약 10배 낮은 지점)
- 모델을 다시 초기화하고 앞에서 찾은 학습률을 사용해 다시 정상적으로 훈련
옵티마이저
- 평범한 미니배치 경사 하강법보다 더 좋은 옵티마이저를 선택하는 것(+ 이 옵티마이저의 하이퍼파라미터를 튜닝하는 것)도 중요함
배치 크기
- 모델 성능과 훈련 시간
- 큰 배치 크기를 사용하는 것의 장점은 GPU같은 하드웨어 가속기를 효율적으로 활용할 수 있다는 점 -> 훈련 알고리즘이 초당 더 많은 샘플을 처리할 수 있음
- 하지만 실전에서 큰 배치를 사용하면 훈련 초기에 종종 불안정하게 훈련됨 -> 작은 배치 크기로 훈련된 모델만큼 일반화 성능을 내지 못할 수 있음
- 작은 배치가 적은 훈련 시간으로 더 좋은 모델을 만드므로, 2~32 까지의 배치를 사용하는 것이 바람직하다는 논문이 있음
- 반대로 학습률 예열 같은 기법으로 매우 큰 배치 크기를 사용할 수 있다는 논문도 있음
- 큰 배치 크기는 일반화 성능에 영향을 미치지 않고 훈련 시간을 매우 단축함
- 훈련이 불안정하거나 최종 성능이 만족스럽지 못하다면 작은 배치 크기를 사용
활성화 함수
- 일반적으로 ReLU 활성화 함수가 모든 은닉층에 좋은 기본값
- 출력층의 활성화 함수는 수행하는 작업에 따라 달라짐
반복 횟수
- 대부분의 경우 훈련 반복 횟수는 튜닝하지 않고, 조기 종료를 사용함
※ 최적의 학습률은 다른 하이퍼 파라미터에 의존적임
- 특히 배치 크기에 영향을 많이 받음
- 다른 하이퍼파라미터를 수정하면 학습률도 반드시 튜닝해야 함
신경망 하이퍼파라미터 튜닝의 모범 사례
'AI > Hands-on ML' 카테고리의 다른 글
[핸즈온 머신러닝] 14장(2) - CNN 구조 (LeNet-5, AlexNet, GoogLeNet, VGGNet, ResNet, Xception , SENet) (0) | 2021.04.01 |
---|---|
[핸즈온 머신러닝] 14장(1) - 합성곱 신경망을 사용한 컴퓨터 비전 (0) | 2021.03.21 |
[핸즈온 머신러닝] 10장 - 케라스를 사용한 인공 신경망 2 (케라스로 딥러닝하기) (0) | 2021.03.06 |
[핸즈온 머신러닝] 10장 - 케라스를 사용한 인공 신경망 1 (인공 신경망 소개) (0) | 2021.02.22 |
[핸즈온 머신러닝] 9장 - 비지도 학습 2 (가우시안 혼합) (0) | 2021.02.05 |