sklearn
의 train_test_split
을 사용해서 간편하게 분리해 볼 수 있다.from sklearn.model_selection import train_test_split
# 예제 데이터 (X: 특성, y: 레이블)
X = [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]]
y = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print("훈련 세트:", X_train, y_train)
print("테스트 세트:", X_test, y_test)
훈련 세트: [[1], [8], [3], [10], [5], [4], [7]] [0, 1, 0, 1, 0, 1, 0]
테스트 세트: [[9], [2], [6]] [0, 1, 1]
unsqueeze
함수가 사용됨Dataset
Dataset
클래스는 데이터셋을 정의하는 기본 클래스Dataset
클래스를 상속받아 커스터마이즈할 수 있습니다.__len__()
: 데이터셋의 크기(샘플 수)를 반환합니다.__getitem__(index)
: 인덱스에 해당하는 데이터를 반환합니다.from torch.utils.data import Dataset
class CustomDataset(Dataset):
def __init__(self, data, labels):
self.data = data
self.labels = labels
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
sample = self.data[idx]
label = self.labels[idx]
return sample, label
DataLoader
DataLoader
클래스는 Dataset
에서 데이터를 로딩dataset
: Dataset
객체를 입력으로 받습니다.batch_size
: 한 배치에 포함할 샘플 수를 지정합니다.shuffle
: 데이터를 매 epoch마다 무작위로 섞을지 여부를 지정합니다.num_workers
: 데이터 로딩을 병렬 처리할 스레드 수를 지정합니다.from torch.utils.data import DataLoader
# DataLoader 객체 생성
dataloader = DataLoader(dataset, batch_size=2, shuffle=True, num_workers=1)
# 데이터 로딩 예제
for batch in dataloader:
samples, labels = batch
print(samples, labels)
로지스틱 회귀(Logistic Regression)는 이진 분류 문제를 해결하기 위해 널리 사용되는 알고리즘입니다. 주로 두 가지 클래스 중 하나로 데이터를 분류하는 데 사용되며, 특히 확률적 해석이 가능한 모델입니다. 로지스틱 회귀는 선형 회귀와 비슷하지만, 출력값을 확률로 변환하여 이진 분류를 수행합니다.
x
와 파리미터 벡터w
의 선형 조합을 계산w
는 가중치 벡터, b
는 편향(basis)z
를 시그모이드 함수를 통과시켜 0과 1사이의 확률로 변환p
p
가 0.5 보다 크면 클래스 1로, 그렇지 않으면 클래스 0으로 예측import torch
import torch.nn as nn
class LogisticRegression(nn.Module):
def __init__(self, input_dim, output_dim):
super(LogisticRegression, self).__init__()
# 선형 계층 정의: 입력 차원 -> 출력 차원
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
# 선형 계층을 통해 입력 데이터를 통과시키고 시그모이드 함수 적용
out = self.linear(x)
out = torch.sigmoid(out) # sigmoid 를 이용하여 결과 값을 0~1로 압축
return out
PyTorch
에서는 교차 엔트로피 손실 함수를 nn.BCELoss
클래스를 통해 사용할 수 있음DataLoader
를 사용하여 미니 배치로 데이터를 불러오고, 각 미니배치에 대해 모델을 학습시키는 방식을 사용데이터 준비 및 DataLoader
생성
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# Logistic Regression 모델 정의
class LogisticRegression(nn.Module):
def __init__(self, input_dim, output_dim):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
out = self.linear(x)
out = torch.sigmoid(out)
return out
# 입력 데이터 및 레이블 (예시 데이터)
X_train = torch.tensor([[1.0, 2.0], [2.0, 3.0], [3.0, 4.0], [4.0, 5.0], [5.0, 6.0], [6.0, 7.0]], dtype=torch.float32)
y_train = torch.tensor([[0.0], [0.0], [1.0], [1.0], [1.0], [0.0]], dtype=torch.float32)
# TensorDataset과 DataLoader를 사용하여 데이터셋을 미니배치로 나누기
dataset = TensorDataset(X_train, y_train)
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
모델 및 학습 설정
# 모델 초기화
input_dim = X_train.shape[1] # 입력 피처의 수
output_dim = 1 # 출력 차원 (이진 분류의 경우 1)
model = LogisticRegression(input_dim, output_dim)
# 손실 함수 및 옵티마이저 정의
criterion = nn.BCELoss() # Binary Cross-Entropy Loss
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 학습 설정
num_epochs = 1000 # 전체 학습 반복 횟수
학습 루프
# 모델을 학습 모드로 설정
model.train()
# 학습 루프
for epoch in range(num_epochs):
epoch_loss = 0.0
for batch in dataloader:
X_batch, y_batch = batch # 미니배치 불러오기
# 순전파: 모델에 입력 데이터를 전달하여 출력값 계산
outputs = model(X_batch)
# 손실 계산
loss = criterion(outputs, y_batch)
# 역전파 및 옵티마이저 스텝 (파라미터 업데이트)
optimizer.zero_grad() # 옵티마이저의 기울기 초기화
loss.backward() # 역전파를 통해 기울기 계산
optimizer.step() # 옵티마이저가 파라미터 업데이트
# 배치 손실을 누적
epoch_loss += loss.item() * X_batch.shape[0]
# 평균 손실 계산
epoch_loss /= len(dataset)
# 학습 진행 상황 출력 (매 100 에포크마다)
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}')
# 학습이 끝나면 모델을 평가 모드로 전환
model.eval()
# 평가 모드에서 모델 테스트 (예시 데이터)
with torch.no_grad(): # 평가 시에는 기울기 계산을 하지 않음
test_outputs = model(X_train)
print("Test outputs after training:", test_outputs)
결과 확인
Epoch [100/1000], Loss: 0.7071
Epoch [200/1000], Loss: 0.6871
Epoch [300/1000], Loss: 0.6651
Epoch [400/1000], Loss: 0.6644
Epoch [500/1000], Loss: 0.6619
Epoch [600/1000], Loss: 0.6909
Epoch [700/1000], Loss: 0.6869
Epoch [800/1000], Loss: 0.6610
Epoch [900/1000], Loss: 0.6928
Epoch [1000/1000], Loss: 0.6928
tensor([[0.3268],
[0.3961],
[0.4699],
[0.5450],
[0.6181],
[0.6862]])