모두의 딥러닝/강의자료 정리

Lab 07-1: Tips(Overfitting, Preprocessing Data)

cvlab_김준수 2025. 1. 21. 16:12

 

Overfitting

Overfitting을 막기위해서 여러 방법이 있지만, 학습할 데이터를 한번에 학습에 사용하지 않고, 80퍼센트만 학습에 사용하고 나머지 20퍼센트의 데이터를 학습에 사용해서 학습에 사용된 데이터에 과적합되었는지 확인하는 방법이 있다. 

 

이 방법을 코드로 생성하면 아래와 같다.

 

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# For reproducibility: 동일한 결과를 재현할 수 있도록 랜덤 시드를 고정
torch.manual_seed(1)

# 훈련 데이터와 테스트 데이터 생성
x_train = torch.FloatTensor([[1, 2, 1],
                             [1, 3, 2],
                             [1, 3, 4],
                             [1, 5, 5],
                             [1, 7, 5],
                             [1, 2, 5],
                             [1, 6, 6],
                             [1, 7, 7]
                            ])
y_train = torch.LongTensor([2, 2, 2, 1, 1, 1, 0, 0])

# 테스트 데이터 생성
x_test = torch.FloatTensor([[2, 1, 1], [3, 1, 2], [3, 3, 4]])
y_test = torch.LongTensor([2, 2, 2])

# 모델 정의: 소프트맥스 분류기를 포함하는 신경망 정의
class SoftmaxClassifierModel(nn.Module):
    def __init__(self):
        super().__init__()
        # 입력 크기 3, 출력 크기 3의 선형 계층 정의 (가중치와 편향 포함)
        self.linear = nn.Linear(3, 3)
    
    def forward(self, x):
        # 선형 계층을 통해 출력 계산
        return self.linear(x)

# 모델 생성
model = SoftmaxClassifierModel()

# 옵티마이저 정의: 확률적 경사하강법(SGD) 사용
optimizer = optim.SGD(model.parameters(), lr=0.1)

# 훈련 함수 정의: 모델 학습
def train(model, optimizer, x_train, y_train):
    nb_epochs = 20  # 총 학습 epoch 수
    for epoch in range(nb_epochs):

        # 모델을 통해 예측값 계산 (H(x))
        prediction = model(x_train)

        # 비용 함수 계산: CrossEntropy 사용
        cost = F.cross_entropy(prediction, y_train)

        # 비용을 기준으로 모델의 파라미터 업데이트
        optimizer.zero_grad()  # 기울기 초기화
        cost.backward()  # 비용 함수의 기울기 계산
        optimizer.step()  # 파라미터 업데이트

        # 학습 진행 상황 출력
        print('Epoch {:4d}/{} Cost: {:.6f}'.format(
            epoch, nb_epochs, cost.item()
        ))

# 테스트 함수 정의: 모델 평가
def test(model, optimizer, x_test, y_test):
    # 모델을 통해 예측값 계산
    prediction = model(x_test)

    # 예측된 클래스 추출 (argmax)
    predicted_classes = prediction.max(1)[1]

    # 정확하게 예측된 샘플 수 계산
    correct_count = (predicted_classes == y_test).sum().item()

    # 비용 함수 계산 (테스트 데이터에서)
    cost = F.cross_entropy(prediction, y_test)

    # 정확도와 비용 출력
    print('Accuracy: {}% Cost: {:.6f}'.format(
         correct_count / len(y_test) * 100, cost.item()
    ))

# 모델 학습 수행
train(model, optimizer, x_train, y_train)

# 모델 평가 수행
test(model, optimizer, x_test, y_test)

 

 

 

Preprocessing Data

모델의 성능을 향상 시키기위해서는 데이터를 입맛에 맞게 변경하는 것도 중요하다. 튀는 데이터를 없애고, 평균을 0으로 맞추고, 표준편차를 1로만들면 모델이 각 특성의 스케일 차이에 영향을 받지 않고 학습할 수 있게된다.

 

그 과정을 코드로 살펴보자.

 

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# 재현성을 위해 랜덤 시드 고정
torch.manual_seed(1)

# 훈련 데이터 생성
x_train = torch.FloatTensor([
    [73, 80, 75],
    [93, 88, 93],
    [89, 91, 90],
    [96, 98, 100],
    [73, 66, 70]
])
y_train = torch.FloatTensor([
    [152],
    [185],
    [180],
    [196],
    [142]
])

# 데이터 전처리: 평균을 0으로 맞추고 표준편차를 1로 정규화
mu = x_train.mean(dim=0)        # 각 특성의 평균 계산
sigma = x_train.std(dim=0)      # 각 특성의 표준편차 계산
norm_x_train = (x_train - mu) / sigma  # 정규화 수행

print("정규화된 입력 데이터 (norm_x_train):")
print(norm_x_train)

# 모델 정의: 다변량 선형 회귀 모델
class MultivariateLinearRegressionModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(3, 1)  # 입력 특성 3개, 출력 1개

    def forward(self, x):
        return self.linear(x)

# 모델 생성
model = MultivariateLinearRegressionModel()

# 옵티마이저 정의: 확률적 경사 하강법(SGD) 사용
optimizer = optim.SGD(model.parameters(), lr=1e-1)

# 훈련 함수 정의: 모델 학습
def train(model, optimizer, x_train, y_train):
    nb_epochs = 20  # 총 학습 epoch 수
    for epoch in range(nb_epochs):
        # 모델을 통해 예측값 계산 (H(x))
        prediction = model(x_train)

        # 비용 함수 계산: 회귀 문제이므로 MSE 손실 함수 사용
        cost = F.mse_loss(prediction, y_train)

        # 비용을 기준으로 모델의 파라미터 업데이트
        optimizer.zero_grad()  # 기울기 초기화
        cost.backward()        # 비용 함수의 기울기 계산
        optimizer.step()       # 파라미터 업데이트

        # 학습 진행 상황 출력
        print('Epoch {:4d}/{} Cost: {:.6f}'.format(
            epoch + 1, nb_epochs, cost.item()
        ))

# 모델 학습 수행
train(model, optimizer, norm_x_train, y_train)