실제로 효과적인 모델을 생성하는데 필요한 기본적인 기능들을 추가해보겠습니다.
검증(validation) 추가하기
이전 포스팅에서 훈련 데이터를 사용하기 위해 합리적인 훈련 루프를 설정하려 했습니다.
과적함인지 확인하기 위해 실제로는 항상 검증 데이터 셋을 갖고 있어야 합니다.
배치와 과적합 사이에 상관관계를 방지하기 위해 훈련 데이터를 섞는 것은 중요합니다.
반면에 검증 손실은 검증 셋을 섞었는지 안섞었는지 동일합니다.
따라서 데이터를 섞는 것은 추가 시간이 필요하기 때문에, 검증 데이터를 섞을 필요는 없습니다.
훈련 셋의 배치 크기 2배로 검증 셋에 대한 배치 크기를 사용하겠습니다.
검증 셋은 역전파가 필요없기 때문에 적은 메모리를 사용합니다.
(기울기를 저장할 필요가 없기 때문입니다.)
큰 배치 크기를 사용하는 이점으로 손실을 더 빨리 계산하겠습니다.
train_ds = TensorDataset(x_train, y_train)
train_dl = DataLoader(train_ds, batch_size=bs, shuffle=True)
valid_ds = TensorDataset(x_valid, y_valid)
valid_dl = DataLoader(valid_ds, batch_size=bs * 2)
각 epoch가 끝날 때 검증 손실을 계산하고 출력할 것입니다.
(훈련 전에 항상 modet.train() 를 호출하고 추론 전에 model.evel() 를 호출해야 합니다. 이는 훈련과 추론에서 적절한 동작이 일어나기 위한 nn.BatchNorm2d 와 nn.Dropout 로서 사용됩니다.)
model, opt = get_model()
for epoch in range(epochs):
medel.train()
for xb, yb in train_dl:
pred = model(xb)
loss = loss_func(pred, yb)
loss.backward()
opt.step()
opt.zero_grad()
model.eval()
with torch.no_grad():
valid_loss = sum(loss_func(model(xb), yb) for xb, yb in valid_dl)
print(epoch, valid_loss / len(valid_dl))
Out :
0 tensor(0.3456)
1 tensor(0.2954)
fit() 와 get_data() 생성하기
코드를 약간 재구성 할것입니다.
훈련 셋과 검증 셋에 대한 손실을 계산하는 것은 동일한 과정을 두 번 진행하기 때문에 하나의 배치에 대한 손실을 계산하는 loss_batch 함수를 만들 것입니다.
훈련 셋에 대한 optimizer 를 전달하고 역전파를 실행하기 위해 이것을 사용하겠습니다.
검증 셋에 대해서 optimizer 를 전달하지 않으므로 매서드는 역전파를 수행하지 않습니다.
def loss_batch(model, loss_func, xb, yb, opt=None):
loss = loss_func(model(xb), yb)
if opt is not None:
loss.backward()
opt.step()
opt.zero_grad()
return loss.item(), len(xb)
fit 은 모델을 훈련하기 위한 필수적인 연산을 수행하고 각 epoch 마다 훈련 손실과 검증 손실을 계산합니다.
import numpy as np
def fit(epochs, model, loss_func, opt, train_dl, valid_dl):
for epoch in range(epochs):
model.train()
for xb, yb in train_dl:
loss_batch(model, loss)func, xb, yb, opt)
model.eval()
with torch.no_grad():
losses, nums = zip(
*[loss_batch(model, loss_func, xb, yb) for xb, yb in valid_dl]
)
val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)
print(epoch, val_loss)
get_data 는 훈련 및 검증 셋에 대한 dataloader 를 출력합니다.
def get_data(train_ds, valid_ds, bs):
return (
DataLoader(train_ds, batch_size=bs, shuffle=True),
DataLoader(valid_ds, batch_size=bs * 2),
)
dataloader를 가져오고 모델을 훈련하는 전체 과정은 3줄의 코드로 실행할 수 있습니다.
train_dl, valid_dl = get_data(train_ds, valid_ds, bs)
model, opt = get_model()
fit(epochs, model, loss_func, opt, train_dl, valid_dl)
Out :
0 0.31335331709384917
1 0.2960355970978737
다양한 모델을 훈련하기 위해 이 기본적인 3줄의 코드를 사용할 수 있습니다.
다음 포스팅에서는 합성곱 신경망(CNN)을 훈련하기 위해 이 코드를 사용할 수 있는지 알아보겠습니다.
공부 목적으로 PyTorch 튜토리얼 홈페이지를 번역해보았습니다.
'Python > PyTorch 공부' 카테고리의 다른 글
[Object Detection] YOLO(v3)를 PyTorch로 바닥부터 구현하기 - Part 2 (8) | 2021.01.11 |
---|---|
[Object Detection] YOLO(v3)를 PyTorch로 바닥부터 구현하기 - Part 1 (5) | 2021.01.10 |
[PyTorch] 3. 파이토치 Dataset, DataLoader 를 사용하여 깔끔한 코드 작성하기 (0) | 2020.12.08 |
[PyTorch] 2. 파이토치 torch.nn을 사용해서 신경망 구축하기 (0) | 2020.12.08 |
[Pytorch] 1. MNIST 데이터를 불러오고 파이토치 없이 신경망 구현하기 (0) | 2020.12.07 |