과적합을 방지하고 모델의 일반화 성능을 향상시키는 기법들
1. 과적합이란?
증상
- 훈련 데이터에서는 높은 성능
- 검증/테스트 데이터에서는 낮은 성능
- 훈련 손실 << 검증 손실
원인
- 모델이 너무 복잡
- 데이터가 부족
- 학습 시간이 너무 길음
해결책
→ 정규화 기법 사용!
2. 가중치 감쇠 (Weight Decay)
L2 정규화 (Ridge)
효과:
- 가중치를 작게 유지
- 모델을 단순화
- 과적합 방지
하이퍼파라미터:
- : 정규화 강도 (보통 0.0001 ~ 0.01)
코드:
# PyTorch
optimizer = torch.optim.Adam(model.parameters(), weight_decay=0.0001)
# Keras
from tensorflow.keras.regularizers import l2
model.add(Dense(128, activation='relu', kernel_regularizer=l2(0.0001)))
L1 정규화 (Lasso)
효과:
- 일부 가중치를 정확히 0으로 만듦
- 특징 선택 효과
- 희소성 (Sparsity)
코드:
# Keras
from tensorflow.keras.regularizers import l1
model.add(Dense(128, activation='relu', kernel_regularizer=l1(0.0001)))
선택 가이드
정규화 | 특징 | 사용 시기 |
---|---|---|
L2 | 가중치를 작게 | 일반적인 경우 |
L1 | 일부 가중치를 0으로 | 특징 선택 필요 |
3. 드롭아웃 (Dropout) ⭐
훈련 중 무작위로 일부 뉴런을 비활성화하는 기법
작동 원리
훈련 시:
- 확률 로 뉴런 유지
- 확률 로 뉴런 제거
테스트 시:
- 모든 뉴런 사용
- 출력에 곱함 (또는 훈련 시 스케일링)
시각화
훈련 시 (p=0.5):
입력층 은닉층 (일부 비활성화) 출력층
○ ------ ○ ------
× (꺼짐)
○ ------ ○ ------
\/
○ ------ × (꺼짐)
테스트 시:
모든 뉴런 활성화
효과
- 앙상블 효과: 여러 서브 네트워크를 학습하는 효과
- Co-adaptation 방지: 뉴런 간의 과도한 의존성 감소
- 일반화 성능 향상
Dropout 비율 가이드
층 종류 | 추천 비율 |
---|---|
Fully Connected Layer | p = 0.5 (keep) |
CNN | p = 0.8 ~ 0.9 (작게) |
RNN | p = 0.5 ~ 0.8 |
입력층 | p = 0.8 ~ 0.9 (작게) |
코드 예시
# Keras
from tensorflow.keras.layers import Dropout
model = keras.Sequential([
Dense(128, activation='relu'),
Dropout(0.5), # 50% 드롭아웃
Dense(64, activation='relu'),
Dropout(0.3), # 30% 드롭아웃
Dense(10, activation='softmax')
])
# PyTorch
import torch.nn as nn
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.fc1 = nn.Linear(784, 128)
self.dropout1 = nn.Dropout(0.5)
self.fc2 = nn.Linear(128, 64)
self.dropout2 = nn.Dropout(0.3)
self.fc3 = nn.Linear(64, 10)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.dropout1(x)
x = torch.relu(self.fc2(x))
x = self.dropout2(x)
x = self.fc3(x)
return x
# 훈련 모드
model.train() # Dropout 활성화
# 평가 모드
model.eval() # Dropout 비활성화
4. 배치 정규화 (Batch Normalization) ⭐
각 미니배치에서 활성화 값을 정규화하는 기법
작동 원리
1단계: 정규화
- : 배치 평균
- : 배치 분산
- : 수치 안정성 (보통 )
2단계: 스케일 & 시프트 (학습 가능)
- , : 학습 가능한 파라미터
효과
- ✅ 학습 속도 향상 (2~10배)
- ✅ 높은 학습률 사용 가능
- ✅ 가중치 초기화에 덜 민감
- ✅ 일부 정규화 효과 (Dropout 대체 가능)
- ✅ 기울기 소실/폭발 문제 완화
배치 정규화 위치
방법 1: 활성화 함수 전
Dense → Batch Norm → ReLU
방법 2: 활성화 함수 후
Dense → ReLU → Batch Norm
💡 논란: 둘 다 사용되지만, 일반적으로 활성화 전이 더 많이 사용됨
코드 예시
# Keras
from tensorflow.keras.layers import BatchNormalization
model = keras.Sequential([
Dense(128),
BatchNormalization(), # 배치 정규화
Activation('relu'),
Dense(64),
BatchNormalization(),
Activation('relu'),
Dense(10, activation='softmax')
])
# PyTorch
import torch.nn as nn
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.fc1 = nn.Linear(784, 128)
self.bn1 = nn.BatchNorm1d(128)
self.fc2 = nn.Linear(128, 64)
self.bn2 = nn.BatchNorm1d(64)
self.fc3 = nn.Linear(64, 10)
def forward(self, x):
x = self.bn1(self.fc1(x))
x = torch.relu(x)
x = self.bn2(self.fc2(x))
x = torch.relu(x)
x = self.fc3(x)
return x
주의사항
- 배치 크기가 너무 작으면 통계가 불안정
- RNN에는 부적합 → Layer Normalization 사용
- 테스트 시: 전체 데이터의 이동 평균 사용
5. 레이어 정규화 (Layer Normalization)
배치가 아닌 각 샘플의 특징들을 정규화
Batch Norm vs Layer Norm
Batch Norm | Layer Norm | |
---|---|---|
정규화 축 | 배치 차원 | 특징 차원 |
배치 크기 영향 | 있음 | 없음 |
사용처 | CNN, Fully Connected | RNN, Transformer |
코드
# PyTorch
import torch.nn as nn
layer_norm = nn.LayerNorm(normalized_shape=128)
# Keras
from tensorflow.keras.layers import LayerNormalization
LayerNormalization()
6. 조기 종료 (Early Stopping) ⭐
검증 손실이 개선되지 않으면 학습을 중단
작동 원리
에포크 훈련 손실 검증 손실
1 0.8 0.9
2 0.6 0.7
3 0.5 0.6
4 0.4 0.55 ← 최고 성능
5 0.3 0.56
6 0.2 0.58
7 0.15 0.60 ← 5 에포크 동안 개선 없음 → 중단
코드 구현
# 수동 구현
best_val_loss = float('inf')
patience = 10
counter = 0
for epoch in range(epochs):
train_loss = train(...)
val_loss = validate(...)
if val_loss < best_val_loss:
best_val_loss = val_loss
save_model() # 최고 모델 저장
counter = 0
else:
counter += 1
if counter >= patience:
print("Early stopping!")
break
# 최고 모델 복원
load_model()
# Keras 콜백
from tensorflow.keras.callbacks import EarlyStopping
early_stop = EarlyStopping(
monitor='val_loss',
patience=10,
restore_best_weights=True # 최고 가중치 복원
)
model.fit(X, y, validation_data=(X_val, y_val), callbacks=[early_stop])
7. 데이터 증강 (Data Augmentation)
기존 데이터를 변형하여 학습 데이터를 인위적으로 늘림
이미지 데이터
일반적인 증강 기법:
- 회전 (Rotation)
- 이동 (Translation)
- 확대/축소 (Scaling)
- 좌우 반전 (Horizontal Flip)
- 자르기 (Cropping)
- 밝기 조절
- 색상 변환
코드 (Keras):
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range=20, # 20도 회전
width_shift_range=0.2, # 좌우 20% 이동
height_shift_range=0.2, # 상하 20% 이동
horizontal_flip=True, # 좌우 반전
zoom_range=0.2 # 20% 확대/축소
)
datagen.fit(X_train)
model.fit(datagen.flow(X_train, y_train, batch_size=32), ...)
텍스트 데이터
- 동의어 대체
- 역번역 (Back-translation)
- 무작위 삽입/삭제
효과
- ✅ 데이터 부족 문제 완화
- ✅ 과적합 방지
- ✅ 모델의 강건성 향상
8. 가중치 초기화 (Weight Initialization)
가중치를 어떻게 초기화하느냐가 학습 성공에 큰 영향
잘못된 초기화
모든 가중치를 0으로:
W = 0 # ❌ 절대 금지!
- 대칭 문제: 모든 뉴런이 같은 값 학습
- 모든 뉴런이 동일하게 업데이트
너무 큰 값:
- 기울기 폭발
- 불안정한 학습
너무 작은 값:
- 기울기 소실
- 학습이 느림
Xavier 초기화 (Glorot)
또는 Uniform:
사용 시기:
- ✅ Sigmoid, Tanh 활성화 함수
코드:
# PyTorch
import torch.nn as nn
nn.init.xavier_normal_(layer.weight)
nn.init.xavier_uniform_(layer.weight)
# Keras (기본값)
Dense(128, kernel_initializer='glorot_normal')
He 초기화 ⭐
사용 시기:
- ✅ ReLU 활성화 함수 (가장 많이 사용)
코드:
# PyTorch
nn.init.kaiming_normal_(layer.weight, mode='fan_in', nonlinearity='relu')
# Keras
Dense(128, kernel_initializer='he_normal')
편향 초기화
- 보통 0으로 초기화
- 가중치만 무작위로 초기화
초기화 선택 가이드
활성화 함수 | 추천 초기화 |
---|---|
ReLU | He |
Sigmoid, Tanh | Xavier |
Leaky ReLU | He |
9. 정규화 기법 조합
추천 조합
기본 구성:
model = keras.Sequential([
Dense(256, kernel_initializer='he_normal'),
BatchNormalization(),
Activation('relu'),
Dropout(0.3),
Dense(128, kernel_initializer='he_normal'),
BatchNormalization(),
Activation('relu'),
Dropout(0.3),
Dense(10, activation='softmax')
])
# Weight Decay
optimizer = keras.optimizers.Adam(learning_rate=0.001)
model.compile(optimizer=optimizer, loss='categorical_crossentropy')
조합 순서
Dense → Batch Norm → Activation → Dropout
10. 정규화 기법 비교
기법 | 효과 | 계산 비용 | 사용 빈도 |
---|---|---|---|
Weight Decay | 과적합 방지 | 낮음 | ⭐⭐⭐⭐⭐ |
Dropout | 과적합 방지 | 낮음 | ⭐⭐⭐⭐⭐ |
Batch Norm | 학습 가속 | 중간 | ⭐⭐⭐⭐⭐ |
Early Stopping | 과적합 방지 | 없음 | ⭐⭐⭐⭐⭐ |
Data Augmentation | 데이터 증가 | 높음 | ⭐⭐⭐⭐ |
Layer Norm | RNN 안정화 | 중간 | ⭐⭐⭐ |
핵심 요약
과적합 방지 우선순위
- 🥇 더 많은 데이터 수집 (가장 효과적)
- 🥈 Dropout 추가 (0.3 ~ 0.5)
- 🥉 Weight Decay (0.0001)
- Batch Normalization (학습 속도 + 정규화)
- Early Stopping (항상 사용)
- Data Augmentation (이미지/텍스트)
모델 구성 체크리스트
- ✅ He 초기화 (ReLU 사용 시)
- ✅ Batch Normalization (각 층마다)
- ✅ Dropout (0.3 ~ 0.5)
- ✅ Weight Decay (0.0001)
- ✅ Early Stopping (patience=10)
기억할 것
- 정규화는 과적합 방지가 목적
- 여러 기법을 조합하여 사용
- 검증 세트로 성능을 모니터링
- 과하지 않게 적절히 사용
다음 학습
- 딥러닝_실전_가이드 - 하이퍼파라미터 튜닝과 문제 해결
- 딥러닝_코드_실습 - 실제 프로젝트 구현
← 딥러닝 기초