[PyTorch] Linear Regression(선형 회귀) - Autograd — zerogod 코코딩딩
[PyTorch] Linear Regression(선형 회귀) - Autograd
이전 포스트에서 다루었던 Gradent Tensor에 이어 간단한 선형회귀식을 구현해본다. 선형회귀는 (x, y)로 정의되는 data set에 대해 각 데이터 (x, y)와 최단 거리를 이루는 직선을 찾는 것이다. 즉, 입
zerogod-ai-dev.tistory.com
이전에 Autograd를 공부하며 간단하게 구현했던 선형 회귀 모델을 torch.nn을 이용하여 구현해본다.
우선 torch.nn은 PyTorch의 인공신경망 모듈로, 딥러닝/머신러닝 모델을 만드는데 필요한 레이어와 기능들을 모아 놓은 라이브러리이다. torch.nn은 다음과 같이 다양한 기능을 제공한다.
- nn.Linear: 선형 변환(fully connected layer)를 구현
- nn.Conv2d: 2차원 컨볼루션 레이어
- nn.RNN, nn.LSTM, nn.GRU: RNN 형태의 시퀀셜 모델 레이어
- nn.ReLU, nn.Sigmoid: 활성화 함수(Activation Function)
- nn.Dropout: 드롭아웃(Dropout) 레이어
nn.Module 안에 선언된 다른 서브 레이어(self.fc, self.conv 등)는 자동으로 트리 구조로 등록되어, model.parameters()가 이 트리를 순회하며 파라미터를 관리한다.
nn.Module은 PyTorch 모델의 기본 클래스이다. 사용자 정의 모델을 설계할 때는 nn.Module을 상속받아 설계한다. nn.Module 내부에서 선언된 nn.Linear, nn.Conv2d 등의 레이어나 직접 선언한 파라미터(nn.Parameter)는 모두 model.parameters()를 통해 한 번에 관리할 수 있다. 그 결과 optimizer에 model.parameters()를 전달해면 자동으로 모델 파라미터를 업데이트할 수 있다.
nn.Module 클래스를 상속받으면 반드시 forward라는 메서드를 오버라이딩해야는데, forward 메서드는 입력 텐서가 모델을 거쳐서 어떻게 변환되는지 순서를 정의한다. 즉, forward는 순전파(Forward Propagation)를 수행하며 역전파(Back Propagation)은 autograd에 의해 자동으로 계산된다.
import torch
import torch.nn as nn # PyTorch의 신경망 모듈
from matplotlib import pyplot as plt
# 1. 데이터 준비
x = torch.FloatTensor(range(5)).unsqueeze(1)
y = 2 * x + torch.rand(5, 1)
이전과 동일한 데이터를 준비한다.
# 2. 선형 회귀 모델 정의
class LinearRegressor(nn.Module): # nn.Module을 상속받아 사용자 정의 모델 설계
def __init__(self):
super().__init__() # 부모 클래스(nn.Module) 초기화
self.fc = nn.Linear(
1, 1, bias=True
) # 선형 변환 레이어 정의: 입력 1, 출력 1, 편향 포함
def forward(self, x): # 순전파(Forward Propagation) 정의
y = self.fc(x) # 입력 x에 대해 y = Wx + b 수행
return y
nn.Module을 상속하여 모델을 정의한다. 선형 회귀 모델 $y=wx+b$는 nn.Linear(N, M, bias=True)로 정의할 수 있다. N은 입력 변수의 개수, M은 출력 변수의 개수이다. bias는 기본값이 True이기 때문에 별도로 명시하지 않아도 된다.
fc는 fully-connected layer(선형 변환 레이어)약자로 w의 shape는 (1, 1), b는 scalar 값이 된다.
순전파를 수행하는 forward 메서드는 정의한 레이어 self.fc에 x를 입력한다. 내부적으로 $y=Wx+b$ 계산을 수행하며 반환값 y가 예측값 $\hat{y}$가 된다. forwad는 __call__을 통해 내부적으로 호출된다. 즉, model 인스턴스를 대상으로 model(x)를 호출하면 forward(x)가 실행된다.
# 3. 모델 및 학습 설정
model = LinearRegressor() # 모델 인스턴스 생성
learning_rate = 1e-3 # 학습률 설정
criterion = nn.MSELoss() # 평균 제곱 오차(MSE) 손실 함수 정의
optimizer = torch.optim.SGD(
model.parameters(), lr=learning_rate
) # 확률적 경사 하강법(SGD) 설정
LinearRegressor 클래스의 인스턴스를 생성한다. 이전 모델과 같이 학습률을 설정하고, 손실함수를 MSE로 설정한다. 역시 optimizer는 torch.optim.SGD를 사용하는데, 모델 파라미터로 model.parameters()를 전달하고 있다. parameters()는 nn.Module 내부의 파라미터를 자동으로 optimizer에 전달한다.
# 4. 모델 학습
loss_stack = [] # 각 에포크(epoch)의 손실 값을 저장할 리스트
for epoch in range(1000):
optimizer.zero_grad() # 이전 에포크의 Gradient 초기화
y_hat = model(x) # 순전파로 예측값 계산 (y_hat = Wx + b)
loss = criterion(y_hat, y) # 예측값과 실제값의 손실 계산 (MSE)
loss.backward() # 역전파(Backpropagation)로 Gradient 계산
optimizer.step() # 모델 파라미터 업데이트 (W, b 최적화)
loss_stack.append(loss.item()) # 손실 값을 리스트에 저장
print(f"Epoch {epoch}: {loss.item()}")
LinearRegressor 클래스에서 오버라이딩한 forward 메서드로 순전파를 수행한다. 손실 함수를 통해 손실값을 계산한 후, 역전파, 모델 파라미터 최적화를 수행하고 손실값을 리스트에 저장한다.
# 5. 학습 후 예측값 계산 (Gradient 비활성화)
with torch.no_grad(): # 학습 중이 아니므로 Gradient 계산 비활성화
y_hat = model(x) # 학습된 모델로 예측값 계산
# 6. 결과 시각화
plt.figure(figsize=(10, 5)) # 전체 그래프 크기 설정
# 손실 그래프
plt.subplot(121) # 1행 2열의 첫 번째 그래프
plt.plot(loss_stack) # 손실 값 변화 그래프
plt.title("Loss") # 그래프 제목
# 예측 값과 실제 값 비교
plt.subplot(122) # 1행 2열의 두 번째 그래프
plt.plot(x, y, ".b") # 실제 값 (파란 점)
plt.plot(x, y_hat, "r-") # 예측 값 (빨간 선)
plt.legend(["Ground Truth", "Prediction"]) # 범례 추가
plt.title("Prediction") # 그래프 제목
plt.show() # 그래프 출력
그 결과 다음과 같이 이전 모델과 동일한 결과를 확인할 수 있다.

전체 코드
import torch
import torch.nn as nn # PyTorch의 신경망 모듈
from matplotlib import pyplot as plt
# 1. 데이터 준비
x = torch.FloatTensor(range(5)).unsqueeze(1)
y = 2 * x + torch.rand(5, 1)
# 2. 선형 회귀 모델 정의
class LinearRegressor(nn.Module): # nn.Module을 상속받아 사용자 정의 모델 설계
def __init__(self):
super().__init__() # 부모 클래스(nn.Module) 초기화
self.fc = nn.Linear(
1, 1, bias=True
) # 선형 변환 레이어 정의: 입력 1, 출력 1, 편향 포함
def forward(self, x): # 순전파(Forward Propagation) 정의
y = self.fc(x) # 입력 x에 대해 y = Wx + b 수행
return y
# 3. 모델 및 학습 설정
model = LinearRegressor() # 모델 인스턴스 생성
learning_rate = 1e-3 # 학습률 설정
criterion = nn.MSELoss() # 평균 제곱 오차(MSE) 손실 함수 정의
optimizer = torch.optim.SGD(
model.parameters(), lr=learning_rate
) # 확률적 경사 하강법(SGD) 설정
# 4. 모델 학습
loss_stack = [] # 각 에포크(epoch)의 손실 값을 저장할 리스트
for epoch in range(1000):
optimizer.zero_grad() # 이전 에포크의 Gradient 초기화
y_hat = model(x) # 순전파로 예측값 계산 (y_hat = Wx + b)
loss = criterion(y_hat, y) # 예측값과 실제값의 손실 계산 (MSE)
loss.backward() # 역전파(Backpropagation)로 Gradient 계산
optimizer.step() # 모델 파라미터 업데이트 (W, b 최적화)
loss_stack.append(loss.item()) # 손실 값을 리스트에 저장
print(f"Epoch {epoch}: {loss.item()}")
# 5. 학습 후 예측값 계산 (Gradient 비활성화)
with torch.no_grad(): # 학습 중이 아니므로 Gradient 계산 비활성화
y_hat = model(x) # 학습된 모델로 예측값 계산
# 6. 결과 시각화
plt.figure(figsize=(10, 5)) # 전체 그래프 크기 설정
# 손실 그래프
plt.subplot(121) # 1행 2열의 첫 번째 그래프
plt.plot(loss_stack) # 손실 값 변화 그래프
plt.title("Loss") # 그래프 제목
# 예측 값과 실제 값 비교
plt.subplot(122) # 1행 2열의 두 번째 그래프
plt.plot(x, y, ".b") # 실제 값 (파란 점)
plt.plot(x, y_hat, "r-") # 예측 값 (빨간 선)
plt.legend(["Ground Truth", "Prediction"]) # 범례 추가
plt.title("Prediction") # 그래프 제목
plt.show() # 그래프 출력'PyTorch' 카테고리의 다른 글
| [PyTorch] Cross-Validation(교차 검증) (0) | 2025.01.27 |
|---|---|
| [PyTorch] MLP(Multi-Layer Perceptron) Regression(다층 퍼셉트론을 이용한 회귀) (0) | 2025.01.16 |
| [PyTorch] 데이터 로드 및 전처리 기본 (1) | 2025.01.13 |
| [PyTorch] Linear Regression(선형 회귀) - Autograd (0) | 2025.01.12 |
| [PyTorch] Back Propagation(역전파) - Gradient Tensor (0) | 2025.01.11 |