오버피팅, 가중치 감소, 드롭아웃
오버피팅
오버피팅이란?
- 신경망이 훈련 데이터에만 지나치게 적응되어 그 외의 데이터에는 제대로 대응하지 못하는 상태
기계 학습은 일반적으로 범용성 좋은 모델은 지향하나 훈련 데이터에는 없는 아직 보지 못한 데이터가 주어져도 바르게 식별해내는 모델이 바람직함.
복잡하고 표현력 높은 모델을 만들 수는 있지만 그만큼 오버피팅을 억제하는 기술이 중요
오버피팅은 주로 다음과 같은 경우에 일어남
- 매개변수가 많고 표현력이 높은 모델
- 훈련 데이터가 적음

가중치 감소
오버피팅 억제용으로 예로부터 많이 이용해온 방법 중 하나.
학습 과정에서 큰 가중치에 대해서는 그에 상응하는 큰 페널티를 부과하여 오버피팅을 억제하는 방법.
원래 오버피팅은 가중치 매개변수 값이 커서 발생하는 경우가 많기 때문.
신경망 학습의 목적은 손실 함수의 값을 줄이는 것.
가중치 감소 이미지
- 왼쪽: 가중치 감소 전
- 오른쪽: 가중치 감소 후


드롭아웃
오버피팅을 억제하는 방식으로 손실 함수에 가중치 L2 노름을 더한 가중치 감소 방법을 사용함.
가중치 감소는 간단하게 구현할 수 있고 어느 정도 지나친 학습을 억제 할 수 있음.
신경망 모델이 복잡해지면 가중치 감소만으로는 대응하기 어려워짐.
드롭아웃이란?
- 뉴런을 임의로 삭제하면서 학습하는 방법.
- 훈련 때 은닉층의 누런을 무작위로 골라 삭제
- 삭제된 뉴런은 신호를 전달하지 않게 됨.
- 단, 테스트 시에는 모든 뉴런에 신호를 전달하여 사용

import numpy as np
import matplotlib.pyplot as plt
# --- 제공된 Dropout 클래스 코드 ---
class Dropout:
"""
순전파 때마다 mask에 삭제할 뉴런을 False로 표시한다. mask는 x와 같은 형상의 무작위 배열을
생성하고 그 값이 dropout_ratio보다 큰 원소만 True로 설정한다.
역전파 때의 동작은 ReLU와 같다.
"""
def __init__(self, dropout_ratio=0.5):
self.dropout_ratio = dropout_ratio
self.mask = None
def forward(self, x, train_flg=True):
if train_flg:
# dropout_ratio보다 큰 값만 True (남김)
self.mask = np.random.rand(*x.shape) > self.dropout_ratio
return x * self.mask
else:
# 추론 시에는 전체 값에 (1.0 - dropout_ratio)를 곱하여 스케일링
return x * (1.0 - self.dropout_ratio)
def backward(self, dout):
# 순전파 시 생성된 마스크를 역전파 기울기에 그대로 적용 (삭제된 뉴런은 기울기 0)
return dout * self.mask
print("Dropout 클래스 정의 완료.")
드롭아웃 순전파 그래프

# 가상의 상위 계층에서 넘어온 기울기 (dout)
dout = np.ones_like(input_data) * 0.1 # 모든 기울기가 0.1이라고 가정
print(f"원래 기울기의 합: {np.sum(dout):.2f}")
# Dropout 인스턴스 재사용 (이전 순전파에서 생성된 self.mask가 남아있음)
# backward 메소드 실행
dout_after_dropout = dropout_layer.backward(dout)
print(f"드롭아웃 후 기울기의 합: {np.sum(dout_after_dropout):.2f}")
print(f"드롭아웃 후 0이 된 기울기의 비율: {np.sum(dout_after_dropout == 0) / len(dout_after_dropout):.2f}")
# 결과 해석:
# 순전파에서 삭제된 뉴런(mask가 False인 부분)에 해당하는 기울기는 0이 됩니다.
# 이는 해당 뉴런이 네트워크 학습에 관여하지 않도록 만듭니다.
원래 기울기의 합: 10.00
드롭아웃 후 기울기의 합: 5.40
드롭아웃 후 0이 된 기울기의 비율: 0.46
- 의미: 드롭아웃 계층을 통과하기 전, 상위 계층에서 넘어온 모든 기울기(dout)의 총합이 10.00이라는 의미
- 가정: 코드 예제에서 우리는 모든 입력 데이터 100개에 대해 기울기를 0.1로 가정
- 의미: 드롭아웃 계층의 backward 메소드를 거친 후, 하위 계층(즉, 드롭아웃 바로 이전 계층)으로 전달될 최종 기울기들의 총합이 5.40이라는 의미
- 해석: 기울기의 총합이 10.00에서 5.40으로 감소 이는 역전파 과정에서 일부 뉴런의 기울기가 완전히 차단되어(0이 되어) 학습에 사용되지 않았음을 뜻함.
- 의미 전체 100개의 기울기 중에서 46% (46개)가 0이 되었다는 의미입니다.
- 해석: 이는 순전파 과정에서 dropout_ratio=0.5로 설정했을 때, 무작위로 선택된 약 50%의 뉴런이 학습에서 제외된 것과 일치.
드롭아웃 스크린샷
- 좌측: 드롭아웃 적용 전
- 오른쪽: 드롭아웃 적용 후


앙상블 학습
개별적으로 학습시킨 여러 모델의 출력을 평균 내어 추론하는 방식.
신경망의 맥락에서 얘기하면 가령 같은 구조의 네트워크를 5개 준비하여 따로따로 학습시키고 시험 때는 5개의 출력을 평균내어 답하는 것.
앙상블 학습을 수행하면 신경망의 정확도가 몇%정도 개선된다는 것이 실험적으로 알려져 있음.
앙상블 학습은 드롭아웃과 밀접해, 드롭아웃이 학습 때 뉴런을 무작위로 삭제하는 행위를 매번 다른 모델을 학습시키는 것으로 해석할 수 있음.
뉴런의 출력에 삭제한 비율을 곱함으로써 앙상블 학습에서 여러 모델의 평균을 내는 것과 같은 효과를 얻는 것.
참고
직접 만드는 샘플 코드에서 학습하는데 시간이 너무 오래걸려서 앞으로 작성하는 예제에 대해서 시간을 줄일 방법도 추가알 올아보아야 할 것 같음.


'AI > DeepLearning' 카테고리의 다른 글
| 적절한 하이퍼파라미터 값 찾기 및 구현 실습 (0) | 2025.11.19 |
|---|---|
| 배치 정규화 Batch Normalization + Pytorch 실습 (0) | 2025.11.13 |
| 신경망 학습에서 초기 가중치 설정 (0) | 2025.11.13 |
| SGD, Momentum, AdaGrad, RMSprop, Adam (0) | 2025.11.09 |
| 활성화 함수 계층 기본 구현 정리 (0) | 2025.11.09 |