AI Fundamentals/BITAmin DL

[BITAmin DL] Session 1.3 - DL Basics 3 (Overfitting, Regularization, Normalization, Augmentation, Early Stoping)

Jae. 2024. 1. 29. 20:18
728x90

 

 


1. Overfitting & Underfitting

 

 

 

Overfitting  : Train data에 대해서 과도하게 학습 & Test data에 대해서는 잘 동작 X 

 

 

  • Overfitting은 학습 데이터(Training Set)에 대해 과하게 학습된 상황
  • 따라서 학습 데이터 이외의 데이터(Test Set)에 대해선 모델이 잘 동작하지 못함

 

  • 학습 데이터가 부족하거나, 데이터의 특성에 비해 모델이 너무 복잡한 경우 발생
  • Training Set에 대한 loss는 계속 떨어지는데, Test Set에 대한 loss는 감소하다가 다시 증가

 

 

 

Underfitting : Train data 조차도 학습 X 할 정도로 부족하게 학습 

 

 

  • Underfitting(과소적합)은 이미 있는 Train set도 학습을 하지 못한 상태를 의미
  • Overfitting과 반대되는 상태를 의미

 

 

  • Underfitting이 발생하는 이유
    • 학습 반복 횟수가 너무 적음
    • 데이터의 특성에 비해 모델이 너무 간단함
    • 데이터 양이 너무 적음

 

 

 

 

Errors

 

 

  • $y$ : True target
  • $\hat {y}$ : Predicted output

 

 

  • $h(x)$ : model의 출력
  • $y$ : 정답

 

  • Squared Error : model 출력과 정답과의 차이를 제곱하여 출력
  • Binary Error : model의 출력과 정답이 다르면 1을 출력
  • Data sample에서 발생하는 모든 sample들의 pointwise error들을 모두 합하면 : overall error를 계산 = Loss function

 

 

 

 

  • $E_{train}$ : 모델을 주어진 data set에 맞추어 학습하는데 사용하는 error
    • 주어진 sample에서 model parameter를 최적화 하도록 사용
    • $E_{general}$ 을 approximation 하는데 적합하지 않음

 

 

  • $E_{test}$ : training data와 overlap이 되지 않도록, 전체 Data Set에서 일부 sample을 따로 빼서 Test Sample을 정의 & 해당 Test Sample에서 나타나는 error
    • 이 error가 real world에서 적용할 때 나타나는 $E_{general}$를 표현

 

 

 

  • GOAL: $E_{test}$ 가 0으로 근사하도록 하여 $E_{general}$ 또한 0으로 근사할 수 있다는 기대를 갖게 하는 것이 목적
    • $E_{test} \approx E_{train}$ 
      • 우리가 학습한 Model이 일반적인 성능을 제공할 수 있도록 하는 것 : Variance가 작도록 설계
      • Failure: Overfitting이 발생 (High Variance)
      • Solution: regularization, more data
    • $E_{train} \approx 0$
      • Model의 학습이 잘 되고 있다 (정확도가 올라가고 있다)
      • 편차, Bias가 줄어들고 있다
      • Failure: Underfitting이 발생 (High Bias)
      • Solution: optimization, more complex model

 

 

 

  • Bias가 높을 경우: 너무 Simple한 Model이 전체 Concept을 표현하지 못함
  • Variance가 높을 경우: 작은 변화 혹은 noise에 민감하게 모델이 과도하게 반응

 

  • Model Generality: Variance를 낮춰야 함 (overfitting)
  • Model Accuarcy: Bias를 낮춰야 함 (underfitting)
  • Bias, Variance는 서로 Trade - off 관계

 

+/- sample 2개로 classification: linear model은 high bias, complex model은 high variance

 

 

  • Complex Model: Overfitting occurs, Variance 증가, Bias 감소
  • Simple Model: Underfitting occurs, Variance 감소, Bias 증가
  • Generalization Error를 줄이는 것이 목적

 

 

 

 

 


2. Solution

 

 

 

Curse of Dimension

 

  • 입력 Data / Feature의 차원이 증가한다면 동일한 분석력을 유지하기 위해서는 지수적으로 sample의 숫자가 늘어나야 함  
  • Model의 복잡도 증가 속도 > Data Set sample 수 : Overfitting이 발생하기 쉽다

 

 

 

 

Solution

 

  • Data Augmentation (증가)
  • Regularization (규제화)
    • Weight Decay
    • Dropout
  • Normalization
    • Batch Normalization
  • Early Stopping
  • Ensemble

 

💡 잠깐!
Regularization이라는 말은 '정규화'라고도 불리며 Normalization과 혼동되는 경우가 많다.
또 이 normalization은 표준화(Standardization)와도 자주 헷갈리는 개념이다.

이들의 개념(차이)을 정리하자면,
- 정규화 Normalization은 데이터의 분포가 정규분포에 가깝게 만드는 것, 즉 범위(scale)를 0~1 사이 값으로 바꾸는 것
- 표준화 Standardization은 데이터가 표준 정규분포에 가깝게 만드는 것, 즉 평균이 0이고 분산이 1이 되도록 scaling 하는 것
- 정칙화 Regularization은 오버피팅을 방지하기 위해 weight에 penalty를 부여하는 것이라고 할 수 있다.

 

 

 

 

  • Cross-validation (CV)
  • k-fold cross-validation  : model을 generalize 하는데 도움이 된다
    • Training Set을 k개의 Group으로 구분
    • k-1개의 Group을 training, 1개의 Group을 validation에 사용
    • Training : model parameter를 fitting하는데 사용
    • Validation : model optimization하는데 사용

 


3. Regularization - Weight Decay

 

 

Regularization

 

모델의 과적합을 방지하기 위해 모델의 복잡성을 줄이는 방식

 

  • Weight Decay
  • Dropout

 

 

Weight Decay

 

학습과정에서 큰 파라미터에 대해서는 큰 Penalty를 부여하여 파라미터가 너무 커지는 것을 방지한다

 

Loss Function에 Penalty Term을 추가하여 구현한다

 

 

 

Regularization Expression

 

$Loss(\theta, \lambda | X, Y) = Error(\theta | X, Y) + \lambda Penalty(\theta)$

 

  • Error Function: Squared_Error, Cross_Entropy, Logistic, Hinge Loss 등
  • Penalty: $L_{0}, L_{1}, L_{2}, L_{infinite}$
  • $\theta$는 Model Parameter로 훈련 과정에서 최적화됨
  • $\lambda$는 규제의 정도를 의미
    • Hyper Parameter(Tuning Parameter)로 사용자가 최적의 성능을 얻기 위해 결정

 

 

 

 

 

 

 

  • $\alpha$가 0으로 갈 경우: Model Parameter를 자유롭게 결정 가능
    • Error Function의 최소화
    • 학습 데이터 적합을 더 개선할 수 있음 (Train Loss를 줄임)
    • 제약이 적음 -> 모델이 복잡해짐 -> Overfitting

 

  • $\alpha$가 무한대로 갈 경우: 비용함수를 최소화하기 위해서는 Model Parameter를 0으로 보내야 함
    • Model parameter $\theta$ 감소
    • Model Parameter의 값을 작게 해 Overfitting을 방지할 수 있음
    • 제약이 강함 -> 모델이 단순해짐 -> Underfitting

 

 

 

 

  • L2 Regularization: $Penalty(\theta) = \theta_{1}^{2} + \theta_{2}^{2} + \cdots + \theta_{p}^{2} $ 
    • Model Parameter의 제곱에 대해 penalty를 부여하는 방식
    • 상관관계가 높은 변수들이 존재할 때 효과적인 규제 방법
    • 두 변수 중 하나의 변수의 회귀 계수 값을 크게 감소
    • 규제가 강해질 수록 각 Model Parameter가 0으로 수렴 (0이 되지는 않음)
    • Ridge: L2 Regularization + Regression

 

 

 

  • L1 Regularization: $Penalty(\theta) = \left|\theta_{1} \right| + \left|\theta_{2} \right| + \cdots  +  \left|\theta_{p} \right| $
    • Model Parameter의 절댓값에 대해 penalty를 부여하는 방식
    • 중요한 변수만 선택하고 나머지는 제거할 때 유용한 규제 방법
    • 두 변수 중 더 중요한 변수만 남기고 나머지 변수의 회귀 계수 값을 0으로 만듦
    • 규제가 강해질 수록 각 Model Parameter가 0으로 접근하다가 0이 된다 (Feature Selection = 변수 선택이 가능)
    • Lasso: L1 Regularization + Regression

 

 

 

 


4. Regularization - Dropout

 

 

 

Dropout

 

 

딥러닝에서 사용되는 정규화기법이며, 과적합을 방지하기 위해 개발됨

 

모델의 일부 Neuron을 랜덤하게 제거 후 학습을 진행

 

  • 모델이 특정 뉴런에 과도하게 의존하는 것을 방지
  • 전체적으로 더욱 일반화(generalization)된 모델을 생성 가능 

 

 

 

모델 훈련 과정에서 노드를 임의로 삭제하여 출력이 일부 노드에만 의존하는 것을 방지하여 더 안정적인 예측이 가능

 

  • 훈련 과정에서 매 Feed Forward 계산에서 $p$의 비율로 노드를 삭제하고, 그 대신 각 출력을 $\frac {1} {1-p}$만큼 스케일하여 계산
  • 예측할 때는 모든 노드를 그대로 사용

 

 

DropOut 동작방식

 

  • 랜덤하게 선택한 일부 뉴런을 'Turn OFF'
  • 훈련량에 따라 적용할 비율을 정하는데, 많은 경우 0.5로 설정
  • 학습시에만 적용되고, Test or Prediction시에는 사용되지 않음

 

입력 데이터의 예측 변수에 Noise를 주고, 모델의 표현 능력을 증가

 

 

 

 

 

Dropout Code Implementation

 

 

PyTorch 에서는 nn.Dropout Class를 이용하여 간단히 Dropout Layer를 추가함

 

  • super().__init__() VS super(nn.Module, self).__init__()
파이썬 3에서 super() 함수는 현재 클래스와 그 부모 클래스를 자동으로 찾아, 부모 클래스의 생성자를 호출합니다. 
따라서, super(DropoutModel, self).__init__()와 super().__init__()는 기능적으로 동일합니다.

 

 

import torch
import torch.nn as nn
import torchvision
import torch.nn.functional as F
from torchvision import transforms
from torch.utils.data.dataloader import DataLoader
nn.Dropout(p=0.5)

# Dropout(p=0.5, inplace=False)

 

 

class DropoutModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.layer1 = nn.Linear(784, 1200)
        self.dropout1 = nn.Dropout(0.5)
        self.layer2 = nn.Linear(1200, 1200)
        self.dropout2 = nn.Dropout(0.5)
        self.layer3 = nn.Linear(1200, 10)

    def forward(self, x):
        x = F.relu(self.layer1(x))
        x = self.dropout1(x)
        x = F.relu(self.layer2(x))
        x = self.dropout2
        return self.layer3(x)

 

 

 


5. Normalization

 

 

Normalization (정규화)

 

  • Data Normalization
  • In-Layer Normalization

 

 

신경망 계층의 입력으로 들어가는 데이터의 분포를 일정하게 맞추어 주는 과정

 

안정적으로 빠른 학습을 위해 주로 사용함

 

 

 

Data Normalization (Data Preprocessing)

 

  • 입력 계층에 들어가는 주어진 데이터(X)를 정규화하는 과정
  • 모델 훈련의 일부가 아니라 전처리의 일부
  • MinMax Normalization: 데이터의 최소값 0, 최대값1로 정규화
  • Standardization: 데이터의 평균0, 표준편차 1로 정규화

 

 

 

 

 

In - Layer Normalization (계층 내 정규화)

 

신경망 내부에서 한 계층에서 다음 계층으로 전달되는 입력을 정규화

 

  • Batch Normalization
  • Layer Normalization
  • Weight Normalization

 

 

Batch Normalization (계층 정규화)

 

  • Mini Batch 내에서 각 변수가 같은 분포를 갖도록 정규화
  • Across - Sample
  • 주로 이미지분석 (CNN)에 사용

 

 

Layer Normalization (계층 내 정규화)

 

  • 하나의 표본 내에서 변수들이 같은 분포를 갖도록 정규화
  • Across - Variable
  • 주로 텍스트분석(RNN)에 사용

 

 

Weight Normalization (가중치 정규화)

 

  • 데이터 대신에 모델의 가중치를 정규화

 

 

 


6. Augmentation

 

 

 

Augmentation

 

 

데이터의 핵심 특징은 간직한 채 Noise를 더하여 데이터셋을 확장

 

  • 주로 새로운 이미지를 생성하는데 사용
  • 이미지 분류 모델의 성능을 향상시키는 기술
  • CNN 모델의 성능을 높이고 Overfitting 극복

 

 

Augmentation 기법

 

  • Rotation
  • Flipping
  • Shifting

 

 

  • RandomHorizontalFilp / RandomVerticalFilp: Flip의 확률을 조절
    • RandomHorizontalFlip(): 좌우반전, 수평으로 뒤집음
    • RandomVerticalFilp(): 상하반전, 수직으로 뒤집음
    • Parameter: P (기본값 0.5 = 50%)

 

 

  • RandomAffine
    • 이미지의 Center를 유지하면서 affine transform(회전, 이동)을 진행
    • RandomRotation과 같이 degree를 받아서 회전을 시키지만, Affine Space에서 변형
    • translation=(a,b)를 받아서 horizontal shift와 vertical shift를 주어진 범위내에서 랜덤하게 실행
      • $-image \; width \times a < dx < image \; width \times a$
      • $-image \; height \times b < dy < image \; height \times b$
    • shear과 같이 기울이는 옵션도 존재

 

 

 

  • RandomRotation
    • Input Parameter: degree
    • sequence를 입력 시: (min, max)내에서 랜덤하게 degree 결정
    • single float를 입력 시: (-input, +input) 범위 내에서 랜덤하게 degree를 결정
    • center option으로 회전의 중심점을 지정 가능

 

 

  • ColorJitter
    • brightness: 밝기 조절 (0~1)
    • contrast: 대비 조절 (0~1)
    • saturation: 채도 조절 (0~1)
    • hue: 색상 조절 (-0.5 ~ 0.5)

 

 

 

 

 

Code Implementation

 

 

import torch
from torchvision import transforms
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

# Image Load 및 PyTorch Tensor로 변환
image_path = "test.png"
image = Image.open(image_path).convert("RGB")
image = transforms.ToTensor()(image)

 

 

 

# Data Augmentation을 위한 변환 정의

data_transform = transforms.Compose(
    [
        transforms.RandomRotation(degrees=20),
        transforms.RandomHorizontalFlip(),
        transforms.RandomVerticalFlip(),
        transforms.RandomAffine(degrees=0, translate=(0.2, 0.2)),
        transforms.ColorJitter(brightness=(0.7, 1.3)),
    ]
)

# 증강된 이미지를 시각화
show_aug_image_batch(image, data_transform, n_images=4)

 

 

 

Augmentation Text

 

  • 단어 생략
  • 단어 교환
  • 단어 이동

 

 

 

 

Augmentation의 효과

 

 

  • Overfitting 방지
    • 모델이 훈련 데이터의 다양한 변형에 대해 학습할 수 있도록 하여 과적합을 방지

 

 

  • 성능 향상
    • 더 많은 데이터로 학습할 수록 성능이 향상됨

 

 

  • 데이터 증가
    • 데이터셋 확장을 통한 데이터 증가

 

 

  • 불균형 해소
    • 분류 작업시 Class 불균형 문제를 해결

 

 

 

 


7. Early Stopping

 

 

 

Early Stopping

 

  • Validation Error(검증손실)가 더 이상 개선되지 않을 때 학습을 중단시킴
  • Overfitting을 방지
    • Epoch이 증가할수록 Overfitting이 될 가능성이 높음
    • Epoch이 감소할수록 Underfitting이 될 가능성이 높음
  • Training Time을 단축

 

 

 

Code Implementation

 

EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto')

 

 

  • patience: 평가지표가 연속으로 좋아지지 않았을때 stop하기 위한 최소 횟수
  • delta: 최소로 좋아져야 하는 결과지표 크기 (해당값 미만일 경우 좋아지지 않았다고 판단)
  • verbose: 중간 결과 출력여부

 

 

 

Early Stopping 구현 단계

 

  • 모델의 성능을 평가하기 위한 검증 데이터셋(Validation DataSet) 선정
  • 최적의 성능을 가진 모델을 저장하기 위한 변수 초기화
  • 학습을 중지하기 위한 조기 종료 조건 설정
  • 학습 과정에서 검증 데이터셋의 손실 (Loss)를 기록
  • 검증 데이터셋의 손실이 이전보다 증가하는 경우, 조기 종료 조건을 확인하여 학습 중지

 

 

 

 

 

 

  • early_stopping_epochs: Validation Loss가 해당 value만큼 연속으로 개선되지(감소하지) 않았을 때 early stop
  • best_loss: 현재까지 관찰된 가장 좋은(낮은) Loss
  • early_stop_counter: Validation Loss가 연속으로 best_loss보다 높은 횟수

 

import torch
import torch.nn as nn
import torch.optim as optim


class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(10, 20)
        self.fc2 = nn.Linear(20, 2)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x


model = Net()  # 모델 초기화
criterion = nn.CrossEntropyLoss  # 손실 함수 초기화
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)  # 옵티마이저 초기화

# 조기 종료 변수 초기화
early_stopping_epochs = 5
best_loss = float("inf")  # 양의 무한대
early_stop_counter = 0

# train loop

epochs = 100
for epoch in range(epochs):
    # model train
    model.train()
    train_loss = 0.0

    for data, target in train_loader:
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        train_loss += loss.item() * data.size(0)  # loss는 모든 data sample에서 발생하는 loss들의 합

    # Validation
    model.eval()
    valid_loss = 0.0
    with torch.no_grad():
        for data, target in valid_loader:
            output = model(data)
            loss = criterion(output, target)
            valid_loss += loss.item() * data.size(0)

    # Validation DataSet의 Loss가 이전보다 증가하는 경우
    if valid_loss > best_loss:
        early_stop_counter += 1
    else:
        best_loss = valid_loss
        early_stop_counter = 0

    # early stopping 조건 확인 -> Validation Loss가 연속으로 early_stopping_epoch동안 개선되지 않았을 때 조기종료
    if early_stop_counter >= early_stopping_epochs:
        print("Early Stopping")
        break

 

 

 

 

 

728x90