본문 바로가기
DNN with Keras/TensorFlow

[TensorFlow] 과대적합 / 과소적합 (2)

by goatlab 2022. 6. 15.
728x90
반응형
SMALL

가중치 규제하기

 

오캄의 면도날 (Occam's Razor) 이론에서는 어떤 것을 설명하는 두 가지 방법이 있다면 더 정확한 설명은 최소한의 가정이 필요한 가장 "간단한" 설명일 것이다. 이는 신경망으로 학습되는 모델에도 적용된다. 훈련 데이터와 네트워크 구조가 주어졌을 때 이 데이터를 설명할 수 있는 가중치의 조합 (즉, 가능한 모델)은 많다. 간단한 모델은 복잡한 것보다 과대적합되는 경향이 작을 것이다.

 

여기서 "간단한 모델"은 모델 파라미터의 분포를 봤을 때 엔트로피 (entropy)가 작은 모델이다 (또는 적은 파라미터를 가진 모델). 따라서, 과대적합을 완화시키는 일반적인 방법은 가중치가 작은 값을 가지도록 네트워크의 복잡도에 제약을 가하는 것이다. 이는 가중치 값의 분포를 좀 더 균일하게 만들어 준다. 이를 "가중치 규제" (weight regularization)라고 부른다. 네트워크의 손실 함수에 큰 가중치에 해당하는 비용을 추가한다. 이 비용은 두 가지 형태가 있다.

 

  • L1 규제는 가중치의 절댓값에 비례하는 비용이 추가된다 (즉, 가중치의 "L1 노름 (norm)"을 추가).
  • L2 규제는 가중치의 제곱에 비례하는 비용이 추가된다 (즉, 가중치의 "L2 노름"의 제곱을 추가다). 신경망에서는 L2 규제를 가중치 감쇠 (weight decay)라고도 부른다. 가중치 감쇠는 수학적으로 L2 규제와 동일하다.

 

L1 규제는 일부 가중치 파라미터를 0으로 만든다. L2 규제는 가중치 파라미터를 제한하지만 완전히 0으로 만들지는 않는다. 이것이 L2 규제를 더 많이 사용하는 이유 중 하나이다.

 

tf.keras에서는 가중치 규제 객체를 층의 키워드 매개변수에 전달하여 가중치에 규제를 추가한다. L2 가중치 규제를 추가한다.

 
l2_model = keras.models.Sequential([
    keras.layers.Dense(16, kernel_regularizer=keras.regularizers.l2(0.001),
                       activation='relu', input_shape=(NUM_WORDS,)),
    keras.layers.Dense(16, kernel_regularizer=keras.regularizers.l2(0.001),
                       activation='relu'),
    keras.layers.Dense(1, activation='sigmoid')
])

l2_model.compile(optimizer='adam',
                 loss='binary_crossentropy',
                 metrics=['accuracy', 'binary_crossentropy'])

l2_model_history = l2_model.fit(train_data, train_labels,
                                epochs=20,
                                batch_size=512,
                                validation_data=(test_data, test_labels),
                                verbose=2)

 

l2(0.001)는 네트워크의 전체 손실에 층에 있는 가중치 행렬의 모든 값이 0.001 * weight_coefficient_value**2만큼 더해진다는 의미이다. 이런 페널티 (penalty)는 훈련할 때만 추가된다. 따라서, 테스트 단계보다 훈련 단계에서 네트워크 손실이 훨씬 더 클 것이다.

 

L2 규제의 효과를 확인한다.

 
plot_history([('baseline', baseline_history),
              ('l2', l2_model_history)])

 

결과에서 보듯이 모델 파라미터의 개수는 같지만 L2 규제를 적용한 모델이 기본 모델보다 과대적합에 훨씬 잘 견디고 있다.

 

드롭아웃 추가하기

 

드롭아웃 (dropout)은 신경망에서 가장 효과적이고 널리 사용하는 규제 기법 중 하나이다. 토론토 (Toronto) 대학의 힌튼 (Hinton)과 그의 제자들이 개발했다. 드롭아웃을 층에 적용하면 훈련하는 동안 층의 출력 특성을 랜덤하게 끈다 (즉, 0으로 만든다). 훈련하는 동안 어떤 입력 샘플에 대해 [0.2, 0.5, 1.3, 0.8, 1.1] 벡터를 출력하는 층이 있다고 가정한다. 드롭아웃을 적용하면 이 벡터에서 몇 개의 원소가 랜덤하게 0이 된다. 예를 들면, [0, 0.5, 1.3, 0, 1.1]가 된다. "드롭아웃 비율"은 0이 되는 특성의 비율이다. 보통 0.2에서 0.5 사이를 사용한다. 테스트 단계에서는 어떤 유닛도 드롭아웃하지 않는다. 훈련 단계보다 더 많은 유닛이 활성화되기 때문에 균형을 맞추기 위해 층의 출력 값을 드롭아웃 비율만큼 줄인다.

 

tf.keras에서는 Dropout 층을 이용해 네트워크에 드롭아웃을 추가할 수 있다. 이 층은 바로 이전 층의 출력에 드롭아웃을 적용한다.

 

IMDB 네트워크에 두 개의 Dropout 층을 추가하여 과대적합이 얼마나 감소하는지 알아 본다.

 
dpt_model = keras.models.Sequential([
    keras.layers.Dense(16, activation='relu', input_shape=(NUM_WORDS,)),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(16, activation='relu'),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(1, activation='sigmoid')
])

dpt_model.compile(optimizer='adam',
                  loss='binary_crossentropy',
                  metrics=['accuracy','binary_crossentropy'])

dpt_model_history = dpt_model.fit(train_data, train_labels,
                                  epochs=20,
                                  batch_size=512,
                                  validation_data=(test_data, test_labels),
                                  verbose=2)
plot_history([('baseline', baseline_history),
              ('dropout', dpt_model_history)])

 

드롭아웃을 추가하니 기준 모델보다 확실히 향상되었다.

 

정리하면 신경망에서 과대적합을 방지하기 위해 가장 널리 사용하는 방법은 다음과 같다.

 

  • 더 많은 훈련 데이터를 모은다.
  • 네트워크의 용량을 줄인다.
  • 가중치 규제를 추가한다.
  • 드롭아웃을 추가한다.

 

마지막으로, 여기서 다루지 않은 중요한 방법 두 가지는 데이터 증식 (data-augmentation)과 배치 정규화 (batch normalization)이다.

 

https://www.tensorflow.org/tutorials/keras/overfit_and_underfit?hl=ko 

 

과대적합과 과소적합  |  TensorFlow Core

Google I/O는 끝입니다! TensorFlow 세션 확인하기 세션 보기 과대적합과 과소적합 Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반

www.tensorflow.org

 

728x90
반응형
LIST