[torch.nn-(3)]
앞선 포스팅에서 training model을 만들고, 그 training set을 torch.nn의 여러 기능을 이용해 좀 더 쉽고 성능 좋게 개선하는 방법을 알아보았다. 이번 포스팅에서는 dataset(x_train, y_train 등) 을 다루는 방법, gpu 사용을 통해 성능을 개선하는 방법을 알아본다.
Refactor using Dataset - (1)
기본적인 tutorial에서 제공하는 방식이다. 먼저, torch.util.data로부터 TensorDataSet을 import한다.
from torch.utils.data import TensorDataset
import tensorflow as tf
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train = torch.tensor(x_train.reshape(60000, 784)/255, dtype=torch.float32)
x_test = torch.tensor(x_test.reshape(10000, 784)/255, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
y_test = torch.tensor(y_test, dtype=torch.int64)
앞서 우리는 위와 같은 code로 training에 필요한 dataset을 가져오고 또 reshape하였다. 이제 여기에 TensorDataSet을 사용하여 x_train, y_train을 묶어서 train_ds라는 변수에 할당한다.
train_ds = TensorDataset(x_train, y_train)
이제 기존 code에서 xs, ys를 직접 idx를 통해 가져왔던 것을 다음 코드 한 줄로 대체할 수 있다.
idx = torch.randint(len(x_train), (batch_size,))
xs, ys = train_ds[idx]
#기존 코드
#xs = x_train[idx]
#ys = y_train[idx]
#
Refactor using Dataset - (2)
앞서 소개한 방법은 dataset을 약간 더 편하게 다룰 수 있는 것 이외에 큰 개선점이 없었다. 이번에는 torch.utils.data.Dataset을 활용하여 class를 만드는 방식으로 dataset을 다루는 방법을 개선한다. 보다 정확히는, 어떠한 dataset을 우리가 원하는 형식으로 다룰 수 있도록, 그 토대가 되는 class를 만드는 것이 목표이다.
class MyDataset(torch.utils.data.Dataset):
def __init__(self, data):
self.data = data
def __getitem__(self, idx):
x = self.data[0][idx]
y = self.data[1][idx]
return x, y
def __len__(self):
return len(self.data[0])
- __init__(self, data): class의 constructor. 생성 시 매개변수로 받는 data를 이 class의 member 변수 data로 지정한다.
- __getitem__(self, idx): data의 각 Item에서 매개변수로 주어진 index의 값을 가져온다. 우리는 x_train(test), y_train(test)을 사용할 것이기 때문에 위와 같이 구현하였다.
- __len__(self): dataset의 길이 파악. data[0]을 사용하기 때문에 여기서는 x_train의 길이를 반환한다.
Refactor using DataLoader
앞서 training을 진행할 때 training은 목표 dataset을 대상으로 batch 단위로 진행된다는 것을 언급하였는데, DataLoader를 사용하여 training dataSet을 어떤 batch 단위로 training 시킬지 지정할 수 있다. 사용법은 아래와 같다.
from torch.utils.data import DataLoader
train_ds = MyDataSet((x_train,y_train))
train_dl = DataLoader((train_ds, batch_size=10))
#batch_size = 10
#train_dl = DataLoader((train_ds, batch_size))
포스팅 [torch.nn-(1)] 부터 여기까지 진행한 결과 최종 코드는 아래와 같다.
model = MyModel()
optimizer = optim.Adam(params=model.parameters(), lr=lr)
for epoch in range(epoch):
for xb, yb in train_dl:
pred = model(xb)
loss = loss_func(pred, yb)
loss.backward()
optimizer.step()
optimizer.zero_grad()
print(loss_func(model(xb), yb))
그러나 Colab의 기본 CPU 모드에서 사용하기에 이 코드는 너무 느리다. Google colab은 사용자가 하드웨어 가속기를 이용할 수 있도록 지원하기 때문에, 해당 기능을 이용하여 학습 속도를 높힐 수 있다.
Colab의 기본 설정은 CPU로 되어 있는데, 런타임>런타임 유형 변경을 통해 그 설정을 변경할 수 있다. 이번 포스팅에서는 TPU(TPU-구글이 제공하는 Tensor Processing Unit)을 사용하였고, 위 최종 코드를 수행한 결과는 아래와 같다.