PyTorch Tutorials
How to Use PyTorch
하계 계절학기와 학부 연구
학기 중에는 학부 과목 공부하느라 랩실에서 많은 활동을 하지 못했다.
주로 논문 스터디를 했으며, 석사 분들의 논문 리뷰를 보며 어떤 부분을 위주로 읽어야 할지 느낌을 잡았다.
그리고, 23년도 하계 방학을 맞이하여 본격적으로 학부인턴 활동을 시작했다.
추가로 자기주도연구도 함께..ㅋㅋ 졸업요건을 충족할 겸 함께 신청했다.
맨 처음에 무엇을 해야 할까 고민을 많이 했지만, 우리 랩실에서 어느정도 출발선까지 실력을 향상시킬 목적으로
멘토-멘티 스터디를 개설했고, 바로 참가했다.
처음은 가볍게 개발환경 세팅을 배웠다.
SSH 세팅, pycharm, 터미널도 새로 설치하고 (아 윈도우 ..) file browser도 설치했다.
이후 python, matplotlib, pytorch 사용법을 수요일까지 익혀오기로 했다.
계절학기도 수강하고 있어서 시작하자마자 할 일이 매우 많아졌다..
아 Tmux도 해야지 :P
PyTorch Quick start
파이썬은 코테할 때 열심히 사용해서 argument parsing쪽만 추가로 공부하기로 했고,
우선 파이토치와 이를 사용하여 모델을 어떻게 구성해야 하는지 찾아보았다.
지금부터 정리하는 내용은 모두 아래의 링크에서 가져온 것임을 알립니다.
https://pytorch.org/tutorials/beginner/basics/intro.html
Learn the Basics — PyTorch Tutorials 2.0.1+cu117 documentation
Note Click here to download the full example code Learn the Basics || Quickstart || Tensors || Datasets & DataLoaders || Transforms || Build Model || Autograd || Optimization || Save & Load Model Learn the Basics Authors: Suraj Subramanian, Seth Juarez, Ca
pytorch.org
1. Datasets & DataLoaders
파이토치에서는 모델에 사용할 데이터를 높은 가독성을 위해 모듈화하여 사용한다.
따라서 아래와 같은 두 가지의 모듈을 제공한다.
torch.utils.data.DataLoader
torch.utils.data.Dataset
아래의 예제는 두 모듈을 이용하여 파이토치에 내장된 FashionMNIST data를 가져온 것이다.
import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor
import matplotlib.pyplot as plt
training_data = datasets.FashionMNIST(
root="data",
train=True,
download=True, # download가 True이면 인터넷에서 다운로드 받는 것을 의미
transform=ToTensor()
)
test_data = datasets.FashionMNIST(
root="data",
train=False,
download=True,
transform=ToTensor()
)
Data를 불러왔다면, 그 다음에 할 일은 위의 data를 DataLoader로 wrapping하는 것이다.
이를 이용하여 매 epoch마다 데이터를 shuffle하여 overfitting을 막아 효과적인 학습이 진행되도록 한다.
이러한 것들을 dataloader로 iterable하게 진행할 수 있다.
from torch.utils.data import DataLoader
train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)
여기서는 batch_size=64이므로 training_data와 test_data를 한 번에 64개씩 볼 것이다.
만약, training을 위해 data에 어떤 조작이 필요하다면, transform을 이용하여 manipulation을 할 수도 있다.
import torch
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda
ds = datasets.FashionMNIST(
root="data",
train=True,
download=True,
transform=ToTensor(),
target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)
이때, parameter로 transform과 target_transform이 있다.
transform은 feature에 변화를 주는 것이고, traget_transform은 class label을 변경할 수 있다.
2. Build the Neural Networks
파이토치에서는 torch.nn에 속한 컴포넌트로 neural networks를 쌓을 수 있다.
따라서 아래와 같이 torch를 nn으로 import하여 사용하자.
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
만약, gpu를 사용할 수 있는 환경이라면 gpu를 사용하는 것이 학습 속도 향상에 큰 도움이 된다.
따라서 cuda를 활성화 하도록 하자.
device = (
"cuda"
if torch.cuda.is_available()
else "mps"
if torch.backends.mps.is_available()
else "cpu"
)
print(f"Using {device} device")
이 코드를 이용하여 cuda를 사용할 수 있는 경우 가속하여 학습을 진행할 수 있다.
Network를 정의하려면 nn.Module을 하위클래스로 정의하고, __init__을 이용하여 network layer를 초기화할 수 있다.
그리고 원하는 layer를 열심히 쌓으면 된다.
class NeuralNetwork(nn.Module):
def __init__(self):
super().__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(x)
logits = self.linear_relu_stack(x)
return logits
위에서 사용한 layer들의 설명은 아래와 같다.
1. nn.Flatten: 2D를 1D로 펼친다.
2. nn.Linear: weight와 bias를 사용하여 linear transformation을 적용한다.
3. nn.ReLU: non-linear activation function으로, 효과적인 학습을 돕는다. (이거 인공지능 시험문제로 나왔는데 :P)
4. nn.Sequential: sequential로 묶은 것들을 차례대로 전달. 즉, layer가 코드에 적은 순서대로 쌓인다.
내가 쌓은 network layer를 확인하려면 device로 옮긴 후에 print를 이용하여 확인할 수 있다.
model = NeuralNetwork().to(device)
print(model)
3. Optimize model parameters
모델을 세웠다면, 이제는 학습을 위하여 parameter를 최적화하여 validation하고 test해야한다.
우선 학습에 필요한 hyperparameter는 다음과 같다.
learning_rate = 1e-3
batch_size = 64
epochs = 5
1. learning rate: 각 batch/epoch마다 모델의 parameter를 얼마나 조절할지에 따른 값이다. 값이 작으면 학습이 느려지고, 값이 크면 parameter 값이 불안정하게 업데이트 될 수 있다.
2. batch size: parameter를 업데이트할 때 사용할 데이터의 수
참고로 iteration은 전체 데이터에 대하여 batch 수를 의미한다.
3. epoch: 전체 데이터셋을 학습한 횟수를 의미한다.
loss function과 optimizer는 아래와 같이 설정할 수 있다.
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
위에서 설정한 hyperparameter를 이용하여 train과 test를 정의하자.
def train_loop(dataloader, model, loss_fn, optimizer):
size = len(dataloader.dataset)
model.train() # Set the model to training mode
for batch, (X, y) in enumerate(dataloader):
# Compute prediction and loss
pred = model(X)
loss = loss_fn(pred, y)
# Backpropagation
loss.backward()
optimizer.step()
optimizer.zero_grad()
if batch % 100 == 0:
loss, current = loss.item(), (batch + 1) * len(X)
print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")
def test_loop(dataloader, model, loss_fn):
model.eval() # Set the model to evaluation mode
size = len(dataloader.dataset)
num_batches = len(dataloader)
test_loss, correct = 0, 0
# Evaluating the model with torch.no_grad() ensures that no gradients are computed during test mode
# also serves to reduce unnecessary gradient computations and memory usage for tensors with requires_grad=True
with torch.no_grad():
for X, y in dataloader:
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")
그리고 설정한 epoch만큼 train과 test iteration을 반복하면 된다.
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train_loop(train_dataloader, model, loss_fn, optimizer)
test_loop(test_dataloader, model, loss_fn)
print("Done!")
4. Save and load the model
모델을 성공적으로 구현하고, 학습이 완료되었다면 이를 저장하는 것도 중요할 것이다.
그래야 다음에 다른 목적으로 사용할 수 있으니까!
pytorch에서는 학습한 parameter를 state_dict에 저장한다. internal dictionary이며 torch.save를 이용하여 저장할 수 있다.
model = models.vgg16(weights='IMAGENET1K_V1')
torch.save(model.state_dict(), 'model_weights.pth')
이 예제에서는 vgg를 이용하여 학습시킨 모델을 저장시킨 것으로 보인다.
나중에 이 모델을 불러오려면 아래와 같이 하면 된다.
model = models.vgg16()
model.load_state_dict(torch.load('model_weights.pth'))
model.eval()
이때 주의할 점은, 반드시 동일한 모델을 선언한 이후 저장해뒀던 parameter를 불러와야 한다는 것이다.
어떻게 보면 당연하다는..
만약, 모델 자체를 저장하고 불러오려면 아래와같이 한다.
# save with models
torch.save(model, 'model.pth')
model = torch.load('model.pth')
5. Make prediction
모델을 학습한 이후 실제 test set을 이용하여 prediction을 진행하는 방법이다.
해당 모델을 test해야 하므로 eval()로 바꿔주고, 예측해보자.
아래는 FashionMNIST를 예측하는 모델이다.
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():
x = x.to(device)
pred = model(x)
predicted, actual = classes[pred[0].argmax(0)], classes[y]
print(f'Predicted: "{predicted}", Actual: "{actual}"')
여기까지가 PyTorch 튜토리얼이었고, 다음엔 Pycharm을 이용하여 실제 모델을 직접 돌려볼 예정이다.
23년 하계 방학은 이전 방학과는 비교가 안 될 정도로 열심히 보낼 것이다 ㅜ.ㅜ