PyTorch로 배우는 경사하강법(Gradient Descent) 코드예제
머신러닝, 딥러닝의 핵심 알고리즘인 경사하강법(Gradient Descent)! 이름은 어렵게 들리지만, 원리는 생각보다 간단합니다. 마치 눈을 가리고 산을 내려가는 것처럼, 가장 가파른 경사를 따라 조금씩 내려가면서 최적의 지점을 찾는 방법이죠.
이번 글에서는 PyTorch 코드를 통해 경사하강법의 핵심 단계를 직접 살펴보고, 각 단계가 어떤 의미를 가지는지 자세히 알아보겠습니다.
1. 준비물: 모델, 손실 함수, 옵티마이저
먼저, 경사하강법을 적용할 모델, 모델의 예측이 얼마나 틀렸는지 평가할 손실 함수, 그리고 경사하강법을 수행할 옵티마이저를 준비해야 합니다.
import torch
import torch.nn as nn
import torch.optim as optim
# 1. 모델 정의 (nn.Module 상속)
class SampleModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(1, 1) # 입력 차원: 1, 출력 차원: 1 (단순 선형 모델)
def forward(self, x): # 순전파 (입력 -> 예측)
return self.linear(x)
# 모델 인스턴스 생성
model = SampleModel()
# 2. 손실 함수 (Loss Function) 정의
criterion = nn.MSELoss() # 평균 제곱 오차 (Mean Squared Error)
# 3. 옵티마이저 (Optimizer) 정의
optimizer = optim.SGD(model.parameters(), lr=0.01) # 확률적 경사하강법 (SGD), 학습률 0.01
- nn.Module: PyTorch에서 모든 신경망 모델의 기본이 되는 클래스입니다. 우리는 nn.Module을 상속받아 SampleModel이라는 새로운 모델을 정의했습니다.
- forward(self, x): 모델의 순전파(forward pass)를 정의하는 함수입니다. 입력 데이터 x를 받아서 모델을 통과시킨 후 예측값을 반환합니다. self.linear는 단순한 선형 변환(y = wx + b)을 수행하는 레이어입니다.
- nn.MSELoss(): 평균 제곱 오차(Mean Squared Error, MSE)를 계산하는 손실 함수입니다. 모델의 예측값과 실제값의 차이를 제곱해서 평균을 낸 값으로, 이 값이 작을수록 모델의 예측이 정확하다는 의미입니다.
- optim.SGD(...): 확률적 경사하강법(Stochastic Gradient Descent, SGD)을 수행하는 옵티마이저입니다. model.parameters()를 통해 모델의 학습 가능한 파라미터(가중치와 편향)를 전달받고, lr=0.01로 학습률을 0.01로 설정했습니다.
2. 학습 루프: 경사하강법의 핵심 단계
이제 준비가 끝났으니, 본격적으로 경사하강법을 수행하는 **학습 루프(training loop)**를 살펴보겠습니다.
# 훈련 데이터 (예시)
x_train = torch.tensor([[1.0], [2.0], [3.0]])
y_train = torch.tensor([[2.0], [4.0], [6.0]])
# -------------------- 학습 루프 (여러 에폭) --------------------
for epoch in range(100): # 100 에폭 동안 반복
# 1. 순전파 (Forward Pass): 입력 데이터를 모델에 통과시켜 예측값 계산
y_pred = model(x_train)
# 2. 손실 (Loss) 계산: 예측값과 실제값(y_train)의 차이(오차) 계산
loss = criterion(y_pred, y_train)
print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')
# 3. 역전파 (Backward Pass): 손실에 대한 각 파라미터의 기울기(gradient) 계산
optimizer.zero_grad() # 기울기 초기화 (이전 에폭의 기울기가 누적되지 않도록)
loss.backward() # 역전파 (자동 미분, autograd)
# # 기울기 확인 (Optional)
# for name, param in model.named_parameters():
# print(f'{name}의 기울기: {param.grad}')
# 4. 파라미터 업데이트: 계산된 기울기를 사용하여 모델의 파라미터(가중치, 편향) 업데이트
optimizer.step() # 경사하강법 적용 (파라미터 업데이트)
- 훈련 데이터: x_train은 입력 데이터, y_train은 실제값(정답)입니다.
- 에폭(Epoch): 전체 훈련 데이터를 한 번 사용하는 것을 1 에폭이라고 합니다. 위 코드에서는 100 에폭 동안 학습을 반복합니다.
- 학습 루프: 각 에폭마다 다음 4단계를 반복합니다.
- 순전파 (Forward Pass): y_pred = model(x_train)
- 입력 데이터 x_train을 모델에 통과시켜 예측값 y_pred를 계산합니다.
- 손실 (Loss) 계산: loss = criterion(y_pred, y_train)
- 예측값 y_pred와 실제값 y_train을 손실 함수 criterion에 넣어 손실(loss)을 계산합니다.
- 역전파 (Backward Pass):
- optimizer.zero_grad(): 이전 에폭에서 계산된 기울기(gradient)를 0으로 초기화합니다. (PyTorch는 기울기를 누적하는 방식으로 동작하기 때문입니다.)
- loss.backward(): 핵심! 역전파를 수행하여 손실에 대한 각 파라미터의 기울기를 자동으로 계산합니다.
- 파라미터 업데이트: optimizer.step()
- 계산된 기울기를 사용하여 모델의 파라미터(가중치, 편향)를 업데이트합니다. optim.SGD는 파라미터 = 파라미터 - 학습률 * 기울기 방식으로 파라미터를 업데이트합니다.
- 순전파 (Forward Pass): y_pred = model(x_train)
핵심 정리:
경사하강법은 위 4단계를 반복하면서 손실 함수의 값을 줄여나가는 알고리즘입니다. 마치 산을 내려가는 것처럼, 손실 함수의 경사를 따라 조금씩 이동하면서 최적의 파라미터 값을 찾는 것이죠.
3. 추가 설명 (Optional)
- 미니배치: 위코드에서는 x_train을 통째로 넣었지만 실제로는 x_train을 배치 사이즈에 맞게 쪼개서 넣어야한다.
- 데이터 셔플: 데이터를 쪼갠 배치를 에폭마다 랜덤하게 섞어줘야한다.
- 기울기 확인: loss.backward()가 끝나면 model.named_parameters()로 모델의 weight와 bias 같은 파라미터들의 기울기를 확인할수있다.
'Python > Deep Learning' 카테고리의 다른 글
| 딥러닝 유사도 측정 (0) | 2025.02.17 |
|---|---|
| [딥러닝] 경사하강법을 사용한 신경망 학습법 (0) | 2025.02.10 |
| [PyTorch] 텐서 연산 (0) | 2025.02.06 |
| [딥러닝] PyTorch에서 Tensor 개념 (0) | 2025.02.05 |
| 딥러닝 발전과정,RNN (0) | 2025.02.03 |