728x90
오늘은 파이토치 라이트닝과 관련해 기본적인 자료가 부족해서 직접 작성해보기로 했다. 공식 홈페이지를 기반으로 했으니, 많이 도움이 될 것이라고 생각한다. 코드는 여기를 참고하면 된다.
대략적인 구조는 다음과 같다.
- 데이터를 모아서 DataLoader를 이용해 train, valid, test로 분할한다.
- Model을 선언한다.
- 훈련때마다 사용하는 방법을 선언한다. (e.g., train_step에서는 어떻게 진행하고 ...)
- Model과 훈련 방법을 Pytorch Lightning Module에 선언한다.
- Hyper Parameter + Lighitning Module을 Trainer에 추가한다.
- Trainer를 통해 훈련된 모델(Trained Model)을 사용한다.
요약
- 라이브러리 설치
- 데이터셋 선언
- 모델 구조 만들기
- Lighitning Module 만들기
- Trainer를 이용해 훈련 및 테스트하기
5가지 단계로 구성되어 있다.
라이브러리 설치 및 선언
pip install torch==2.3.1
pip install torchvision==0.18.1
pip install pytorch_lightning==2.3.3
# 필요한 라이브러리 선언
import os
import torch
import numpy as np
import matplotlib.pyplot as plt
from torch import nn
import torch.nn.functional as F
from torchvision import transforms
from torchvision.datasets import MNIST
from torch.utils import data
import pytorch_lightning as pl
데이터셋 선언(분할) 및 확인
dataset은 손글씨로 유명헌 MNIST 데이터셋을 사용한다. 자세한 정보는 여기를 확인하면 된다.
데이터셋 선언 및 분할
# 데이터 셋 불러오기
train_set = MNIST(os.getcwd(), download=True, train=True, transform=transforms.ToTensor())
test_set = MNIST(os.getcwd(), download=True, train=False, transform=transforms.ToTensor())
# 데이터셋 분할
train_set_size = int(len(train_set) * 0.8)
valid_set_size = len(train_set) - train_set_size
# 8 : 2 비율로 train_set과 valid_set 분할
train_set, valid_set = data.random_split(train_set, [train_set_size, valid_set_size])
데이터 확인
image, label = train_set[0]
image = image.numpy()
image = image.squeeze() # 차원 축소
# 이미지 시각화
plt.imshow(image, cmap='gray')
plt.title(f"answer = {label}")
plt.show()
데이터로더 변환
# DataLoader 변환
train_loader = data.DataLoader(train_set)
valid_loader = data.DataLoader(valid_set)
test_loader = data.DataLoader(test_set)
모델 만들기(Encoder, Decoder)
class Encoder(nn.Module):
def __init__(self):
super().__init__()
self.l1 = nn.Sequential(nn.Linear(28 * 28, 64), nn.ReLU(), nn.Linear(64, 3))
def forward(self, x):
return self.l1(x)
class Decoder(nn.Module):
def __init__(self):
super().__init__()
self.l1 = nn.Sequential(nn.Linear(3, 64), nn.ReLU(), nn.Linear(64, 28 * 28))
def forward(self, x):
return self.l1(x)
Encoder
- 목적: 입력 데이터를 저차원의 표현으로 변환(인코딩).
- 구조:
- nn.Linear(28 * 28, 64): 입력 데이터의 차원을 784(28x28)에서 64로 줄이는 선형 변환을 수행한다.
- nn.ReLU(): 비선형 활성화 함수로, 선형 변환 후 적용되어 모델의 표현력을 증가시킨다.
- nn.Linear(64, 3): 중간 표현의 차원을 64에서 3으로 더 줄여 저차원 특징을 추출한다.
Decoder 클래스
- 목적: 저차원 표현을 다시 원래의 차원으로 확장하여 데이터를 복원(디코딩).
- 구조:
- nn.Linear(3, 64): 저차원 표현(3차원)을 중간 차원(64차원)으로 확장하는 선형 변환을 수행한다.
- nn.ReLU(): 비선형 활성화 함수를 적용하여 데이터의 비선형적 특징을 유지 및 강화한다.
- nn.Linear(64, 28 * 28): 최종적으로 중간 차원을 원래의 입력 데이터 차원(784차원)으로 확장하여 재구성한다.
Lighitning Module 만들기
class LitAutoEncoder(pl.LightningModule):
def __init__(self, encoder, decoder):
super().__init__()
self.encoder = encoder
self.decoder = decoder
def training_step(self, batch, batch_idx):
# training_step defines the train loop.
x, _ = batch
x = x.view(x.size(0), -1)
z = self.encoder(x)
x_hat = self.decoder(z)
loss = F.mse_loss(x_hat, x)
return loss
def validation_step(self, batch, batch_idx):
# this is the validation loop
x, _ = batch
x = x.view(x.size(0), -1)
z = self.encoder(x)
x_hat = self.decoder(z)
val_loss = F.mse_loss(x_hat, x)
self.log("val_loss", val_loss)
def test_step(self, batch, batch_idx):
# this is the test loop
x, _ = batch
x = x.view(x.size(0), -1)
z = self.encoder(x)
x_hat = self.decoder(z)
test_loss = F.mse_loss(x_hat, x)
self.log("test_loss", test_loss)
def configure_optimizers(self):
optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)
return optimizer
각각 함수에 대한 설명과 코드 해석을 하면 다음과 같다.
- __init__(self, encoder, decoder): 생성자에서는 인코더와 디코더 객체를 모듈의 속성으로 저장한다.
- training_step : 훈련 step마다 실행되며, x 입력에 대해 인코딩, 디코딩과정을 통해 정답과 예측에 대해 loss 계산한다.
- validation_step : 검증 step마다 실행되며, training_step과 동일하다.
- test_step : 테스트 step에서 실행되며, training_step과 동일하다.
- configure_optimizers : 학습 과정에서 사용할 옵티마이저를 설정한다. 필요하다면 학습률 스케줄러도 설정할 수 있지만, 여기서는 0.001로 설정한다.
모듈을 이용한 모델 선언
# model
model = LitAutoEncoder(Encoder(), Decoder())
Trainer로 훈련 및 테스트 하기
Trainer 선언
trainer = pl.Trainer(max_epochs=5)
Trainer 내부에 Hyper Parameters 선언하지만, 지금은 간단하게 epoch만 설정했다.
Trainer로 모델 훈련하기
trainer.fit(model, train_loader, valid_loader)
trainer의 fit 함수를 이용하여 train_loader와 valid_loader를 이용해 model 훈련한다.
- train_loader : training_step에서 사용된다.
- valid_loader : validation_step에서 사용된다.
실행하면 다음과 같이 모델 정보(파라미터 수, GPU 정보) 와 함께 실험 예상시간이 출력된다.
Trainer로 모델 테스트하기
trainer.test(model, dataloaders=test_loader)
실행하면 실행에 대한 결과가 출력된다. 여기서 코드 작성을 통해 원하는 metric을 추가할 수 있다.
다음은 훈련된 모델을 불러오고 사용하는 방법에 대해 알아보려고 한다.
'AI & DL > Pytorch Lightning' 카테고리의 다른 글
[Pytorch Lightning] 튜토리얼 3 - GPU를 사용해서 훈련해보자 (1) | 2024.07.23 |
---|---|
[Pytorch Lightning] 튜토리얼 2 - 모델을 저장하고 불러오자 (0) | 2024.07.21 |
[Pytorch Lightning] BART를 이용해 Text를 요약해보자 - 4 (완) (0) | 2024.07.16 |
[Pytorch Lightning] BART를 훈련해 Text를 요약해보자 - 3 (2) | 2024.07.15 |
[Pytorch Lightning] BART를 훈련해 Text를 요약해보자 - 2 (0) | 2024.07.13 |