본문 바로가기
모두의 딥러닝/강의자료 정리

Lab_05: Logistic Regression

by cvlab_김준수 2025. 1. 16.

Logistic Regression란?

: 기존 선형 회귀는 Y의 값이 연속적일 떄 사용 가능한 모델이다. 다만, Y값이 연속적이지 않고 기존 범주중 하나로 예측해야하는 경우 문제가 생기기 때문에 이를 해결하기 위한 방법이 Logistic Regression이다. 

 

예를 들어, 해당 이메일이 스팸인지 아닌지에 대한 것에 대한 예측을 할 때 사용하는 것이다.

 

 

 

 

따라서, 이렇게 특정 범주(0 ~ 1)으로 분류하는 것을 Logistic Regression이라고 하는데, 이때 출력값을 확률로 변환하기 위해서 시그모이드 함수를 적용해서 값을 예측하게 된다. 

 

 

 

이렇게 하면 x의 범위는 무한대이지만, y의 범위는 0 ~ 1로 제한되게 된다. 이렇게  특정 x에 대해서 0 ~ 1로 범위가 지정되어 확률이 나오게된다.

 

 

 Logistic Regression에서는 손실함수로 Cross Entropy를 사용해서 학습을 진행한다. 

 

 

 

이 전체과정을 코드로 보면 아래와 같다. 

 

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

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


# (1) 데이터 로드 및 전처리
try:
    xy = np.loadtxt('data-03-diabetes.csv', delimiter=',', dtype=np.float32)
except FileNotFoundError:
    print("\nError: 'data-03-diabetes.csv' 파일을 찾을 수 없습니다. 파일을 현재 디렉토리에 추가하세요.")
    exit()

x_data = xy[:, 0:-1]  # 모든 행, 마지막 열 제외 (특징)
y_data = xy[:, [-1]]   # 모든 행, 마지막 열 (레이블)

# Tensor로 변환
x_train = torch.FloatTensor(x_data)
y_train = torch.FloatTensor(y_data)



# (2) 모델 정의 (nn.Module 사용)
class BinaryClassifier(nn.Module):
    def __init__(self, input_dim):
        super(BinaryClassifier, self).__init__()
        self.linear = nn.Linear(input_dim, 1)  # 입력 차원과 출력 차원 설정
        self.sigmoid = nn.Sigmoid()
    
    def forward(self, x):
        return self.sigmoid(self.linear(x))

# 모델 초기화: 입력 차원이 8인 경우
input_dim = x_train.shape[1]
model = BinaryClassifier(input_dim=input_dim)


# (3) 손실 함수(Binary Cross Entropy) 및 옵티마이저 설정
criterion = nn.BCELoss()

optimizer = optim.SGD(model.parameters(), lr=1)


# (4) 모델 학습
nb_epochs = 100
for epoch in range(nb_epochs + 1):
    # 가설 계산 (순전파)
    hypothesis = model(x_train)
    
    # 비용 함수 계산
    cost = criterion(hypothesis, y_train)
    
    optimizer.zero_grad()
    cost.backward()
    optimizer.step()
    
    # 10 에폭마다 비용과 정확도 출력
    if epoch % 10 == 0:
        # 예측 변환: 0.5를 기준으로 0 또는 1로 분류
        prediction = hypothesis >= torch.FloatTensor([0.5])
        correct_prediction = prediction.float() == y_train
        accuracy = correct_prediction.sum().item() / len(correct_prediction)
        print(f'Epoch {epoch:4d}/{nb_epochs} Cost: {cost.item():.6f} Accuracy: {accuracy * 100:.2f}%')


# (5) 모델 평가
with torch.no_grad():
    hypothesis = model(x_train)
    prediction = hypothesis >= torch.FloatTensor([0.5])
    correct_prediction = prediction.float() == y_train
    accuracy = correct_prediction.sum().item() / len(correct_prediction)
    print(f'\nThe model has an accuracy of {accuracy * 100:.2f}% for the training set.')


# (6) 예시 출력
with torch.no_grad():
    print("\nHypothesis Samples:")
    print(hypothesis[:5])
    
    print("\nPredictions vs Actual:")
    print(prediction[:5])
    print(y_train[:5])
    
    print("\nCorrect Predictions:")
    print(correct_prediction[:5])