PyTorch를 활용한 선형 회귀 모델 구현

PyTorch의 고수준 API를 활용하면 선형 회귀 모델을 훨씬 간결하게 구현할 수 있다. 이번 글에서는 프레임워크에서 제공하는 다양한 기능을 활용하여 효율적으로 모델을 구축하고 학습하는 방법을 알아본다.

필수 라이브러리 임포트

import torch
from torch import nn
from torch.utils import data
from d2l import torch as d2l

학습 데이터 생성

실제 데이터처럼 보이도록 합성 데이터를 생성한다. 이때 실제 파라미터 값을 정의하고, 이를 기반으로 입력 특성과 레이블을 생성한다.

# 실제 가중치와 편향 정의
actual_weights = torch.tensor([2, -3.4])
actual_bias = 4.2

# 1000개의 샘플 생성
X, y = d2l.synthetic_data(actual_weights, actual_bias, 1000)

데이터 로더 구성

미니배치 학습을 위해 데이터 로더를 구현한다. TensorDataset으로 데이터를 묶고, DataLoader를 통해 배치 단위로 데이터를 제공한다.

def create_dataloader(data_arrays, batch_size, shuffle=True):
    dataset = data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset, batch_size, shuffle=shuffle)

batch_size = 32
train_loader = create_dataloader((X, y), batch_size)

모델 정의

nn.Sequential을 사용하여 선형 레이어 한 개로 모델을 구성한다. 입력 차원은 2, 출력 차원은 1이다.

model = nn.Sequential(nn.Linear(2, 1))

모델 파라미터 초기화

가중치는 정규 분포로, 편향은 0으로 초기화한다.

model[0].weight.data.normal_(mean=0, std=0.01)
model[0].bias.data.zero_()

손실 함수 및 최적화 알고리즘 설정

평균 제곱 오차(MSE)를 손실 함수로 사용하고, 확률적 경사 하강법(SGD)으로 모델을 학습한다.

criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.03)

모델 학습 수행

지정된 에포크 수만큼 반복하여 모델을 학습시킨다. 각 iteration에서 Forward Pass, backward 계산, 파라미터 업데이트 과정을 수행한다.

epochs = 3
for epoch in range(epochs):
    for batch_X, batch_y in train_loader:
        prediction = model(batch_X)
        loss_value = criterion(prediction, batch_y)
        
        optimizer.zero_grad()
        loss_value.backward()
        optimizer.step()
    
    # 에포크 종료 후 전체 데이터에 대한 손실 값 출력
    total_loss = criterion(model(X), y)
    print(f"Epoch {epoch + 1}: 손실 = {total_loss:.6f}")

학습 결과 확인

학습이 완료된 후 모델이 예측한 파라미터와 실제 파라미터之间的 오차를 확인한다.

estimated_weights = model[0].weight.data
estimated_bias = model[0].bias.data

print(f"가중치 추정 오차: {actual_weights - estimated_weights.reshape(actual_weights.shape)}")
print(f"편향 추정 오차: {actual_bias - estimated_bias}")

응용: 옴의 법칙建模

위에서 배운 내용을 바탕으로 옴의 법칙(V = IR + b)을 학습시켜 보자. 전류(I)에서 전압(V)을 예측하는 모델을 만든다.

import torch
from torch import nn
from torch.utils import data
from d2l import torch as d2l

# 옴의 법칙: V = R * I + b
true_resistance = torch.tensor([3.3])
true_offset = 3.5

# 1000개의 전류-전압 데이터쌍 생성
current_data, voltage_data = d2l.synthetic_data(true_resistance, true_offset, 1000)
print(f"전류: {current_data[0]}, 전압: {voltage_data[0]}")
# 배치 단위 데이터 로더 생성
def build_dataloader(inputs, outputs, batch_size, shuffle_flag=True):
    dataset = data.TensorDataset(*(inputs, outputs))
    return data.DataLoader(dataset, batch_size, shuffle=shuffle_flag)

batch_size = 20
loader = build_dataloader(current_data, voltage_data, batch_size)
print(f"데이터 로더 타입: {type(loader)}")
# 전압 예측 모델 구성 (입력: 전류 1개, 출력: 전압 1개)
voltage_model = nn.Sequential(nn.Linear(1, 1))

# 초기화
voltage_model[0].weight.data.normal_(0, 0.01)
voltage_model[0].bias.data.fill_(0)

# 손실 함수 및 최적화
loss_fn = nn.MSELoss()
optimizer = torch.optim.SGD(voltage_model.parameters(), lr=0.05)
# 학습 루프
training_epochs = 5
for epoch in range(training_epochs):
    for I, V in loader:
        predicted_V = voltage_model(I)
        loss = loss_fn(predicted_V, V)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    epoch_loss = loss_fn(voltage_model(current_data), voltage_data)
    print(f"Epoch {epoch + 1}: 손실 = {epoch_loss:.6f}")

# 추정 결과
print(f"저항 추정 오차: {true_resistance - voltage_model[0].weight.reshape(true_resistance.shape)}")
print(f"오프셋 추정 오차: {true_offset - voltage_model[0].bias}")

이처럼 PyTorch의 편리한 API들을 활용하면 최소한의 코드로 효율적인 딥러닝 모델을 구현할 수 있다.

태그: PyTorch linear-regression neural-network deep-learning machine-learning

7월 28일 22:18에 게시됨