1. 파이토치(PyTorch) 튜토리얼 - 빠른 시작(QUICKSTART)

Yeonghyeon·2022년 7월 12일
0
post-custom-banner

본 포스팅은 파이토치(PYTORCH) 한국어 튜토리얼을 참고하여 공부하고 정리한 글임을 밝힙니다.


데이터 작업하기

PyTorch에서 데이터 작업을 위한 기본 요소 2가지
1) torch.utils.data.DataLoader: Dataset을 순회 가능한 객체(iterable)로 감싼다
2) torch.utils.data.Dataset: 샘플과 정답을 저장

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

PyTorch는 TorchText, TorchVision 및 TorchAudio 와 같이 도메인 특화 라이브러리를 데이터셋과 함께 제공하고 있음 ➡️ 이 튜토리얼에서는 TorchVision 데이터셋을 사용

  • torchvision.datasets: CIFAR, COCO 등과 같은 다양한 실제 비전(vision) 데이터에 대한 Dataset을 포함
  • 이 튜토리얼에서는 FasionMNIST 데이터셋 사용
  • 모든 TorchVision Dataset은 샘플과 정답을 각각 변형하기 위한 transformtarget_transform의 두 인자를 포함
# 공개 데이터셋에서 학습 데이터 내려 받음
training_data = datasets.FashionMNIST(
	root="data",
    train=True,
    download=True,
    transform=ToTensor(),
 )
 
 # 공개 데이터셋에서 테스트 데이터 내려 받음
 test_data = datasets.FashionMNIST(
	root="data",
    train=False,
    download=True,
    transform=ToTensor(),
 )

DatasetDataLoader의 인자로 전달하여 데이터셋을 순회 가능한 객체로 감싸고, 자동화된 배치, 샘플링, 섞기(shuffle) 및 다중 프로세스로 데이터 불러오기(multiprocess data loading)을 지원

  • batch_size=64
batch_size = 64

# 데이터로더 생성
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
	print(f"Shape of X [N, C, H, W]: {X.shape}")
    print(f"Shape of y: {y.shape} {y.dtype}")
    break

Out:

Shape of X [N, C, H, W]: torch.Size([64, 1, 28, 28])
Shape of y: torch.Size([64]) torch.int64

모델 만들기

PyTorch에서 신경망 모델은 nn.Module을 상속받는 클래스로 생성하여 정의함

  • __init__ 함수: 신경망의 계층(layer)들을 정의
  • forward 함수: 신경망에 데이터를 어떻게 전달할지 지정
    (GPU로 신경망 이동시켜 연산을 가속)
# 학습에 사용할 CPU/GPU 장치 얻음
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")

# 모델 정의
class NeuralNetwork(nn.Module):
	def __init__(self):
    	super(NeuralNetwork, self).__init__()
		self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
        	nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512,512),
            nn.ReLU(),
            nn.Linear(512,10)
        )
     
    def forward(self, x):
   		x = self.flatten()
        logits = self.linear_relu_stack(x)
        return logits
       
       
model = NeuralNetwork().to(device)
print(model)

Out:

Using cuda device
NeuralNetwork(
  (flatten): Flatten(start_dim=1, end_dim=-1)
  (linear_relu_stack): Sequential(
    (0): Linear(in_features=784, out_features=512, bias=True)
    (1): ReLU()
    (2): Linear(in_features=512, out_features=512, bias=True)
    (3): ReLU()
    (4): Linear(in_features=512, out_features=10, bias=True)
  )
)

모델 매개변수 최적화하기

모델을 학습하려면 손실 함수(Loss Function)과 옵티마이저(Optimizer)가 필요

loss_fn = nn.CrossEntroyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)

각 학습 단계(training loop)에서 모델은 (배치로 제공되는) 학습 데이터셋에 대한 예측을 수행하고, 예측 오류를 역전파하여 모델의 매개변수를 조정

def train(dataloader, model, loss_fn, optimizer):
	size = len(dataloader.dataset)
    for batch, (X, y) in enumerate(dataloader):
    	X, y = X.to(device), y.to(device)
        
        # 예측 오류 계산
        pred = model(X)
        loss = loss_fn(pred, y)
        
        # 역전파
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        if batch % 100 == 0:
        	loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")

모델이 학습하고 있는지를 확인하기 위해 테스트 데이터셋으로 모델의 성능을 확인

def test(dataloader, model, loss_fn):
	size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
    	for X, y in dataLoader:
        	X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

각 에폭마다 모델의 정확도(accuracy)와 손실(loss)을 출력

epochs = 5
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model, loss_fn)
print("Done!")

Out:

Epoch 1
-------------------------------
loss: 2.303634  [    0/60000]
loss: 2.281419  [ 6400/60000]
loss: 2.262224  [12800/60000]
loss: 2.253071  [19200/60000]
loss: 2.215731  [25600/60000]
loss: 2.202008  [32000/60000]
loss: 2.208793  [38400/60000]
loss: 2.169434  [44800/60000]
loss: 2.175368  [51200/60000]
loss: 2.133471  [57600/60000]
Test Error:
 Accuracy: 47.2%, Avg loss: 2.126842
 
...

모델 저장하기

모델을 저장하는 일반적인 방법: (모델의 매개변수들을 포함하여) 내부 상태 사전(internal state dictionary)을 직렬화(serialize)하는 것

torch.save(model.state_dict(), "model.pth")
print("Saved PyTorch Model State to model.pth")

Out:

Saved PyTorch Model State to model.pth

모델 불러오기

모델 구조를 다시 만들고 상태 사전을 모델에 불러오는 과정이 포함됨

model = NeuralNetwork()
model.load_state_dict(torch.load("model.pth"))

모델 사용해서 새로운 예측 가능

classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]

model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
	pred = model(x)
    predicted, actual = classes[pred[0].argmax(0)], classes[y]
    print(f'Predicted: "{predicted}", Actual: "{actual}"')

Out:

Predicted: "Ankle boot", Actual: "Ankle boot"
post-custom-banner

0개의 댓글