Define by Run vs Define and Run
Tensorflow
Define and Run
Pytorch
Define by Run
All datasets are subclasses of torch.utils.data.Dataset i.e, they have __getitem__ and __len__ methods implemented. Hence, they can all be passed to a torch.utils.data.DataLoader which can load multiple samples in parallel using torch.multiprocessing workers.
Dataset stores the samples and their corresponding labels, and DataLoader wraps an iterable around the Dataset to enable easy access to the samples.
Ex>
ImageNet 불러오기
imagenet_data = torchvision.datasets.ImageNet('path/to/imagenet_root/')
data_loader = torch.utils.data.DataLoader(imagenet_data,
batch_size=4,
shuffle=True,
num_workers=args.nThreads)
FashionMNIST 불러오기; 밑의 실습은 이 datasets를 이용
# torchvision.datasets을 통해 데이터 로딩
training_data = datasets.FashionMNIST(
root='data',
train=True,
download=True,
transform=ToTensor()
)
test_data = datasets.FashionMNIST(
root='data',
train=False,
download=True,
transform=ToTensor()
)
참고 : https://pytorch.org/vision/stable/datasets.html
tensorflow.data.Dataset 은 index로 참조할 수 없다.
ds[0] # Raising error
하지만 torch.utils.data.Dataset은 index로 참조할 수 있다.
# device를 가져온다
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f'Using {device} device')
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
# model = NeuralNetwork()
model = NeuralNetwork().to(device)
print(model)
모델을 생성할 때 device를 지정해준다.
텐서플로우는 keras.Model을 상속받았고
파이토치는 torch.nn.Module을 상속받는다.
하지만 텐서플로우는 Functional API 방식을 권장한다.
nn.Linear --> keras.models.Dense
nn.ReLU --> keras.layers.Activation('relu')
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
Train
def train(dataloader, model, loss_fn, optimizer):
size = len(dataloader.dataset)
model.train()
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} [{current/size:>5f}%]')
batch로 묶었기 때문에 data별 총 size --> len(dataloader.dataset)
model.train() --> 모델을 학습 상태로 만든다.
X.to(device) --> device에 올려둔다.
optimizer.zero_grad()
loss.backward()
optimizer.step()
optimizer의 기울기를 단계마다 초기화 하고,
역전파를 통해 Layer의 각 weights loss 계산,
weights를 개선한다.
Test
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")
model.eval() --> 모델을 평가 상태로
with torch.no_grad() --> 학습을 하지 않으므로
loss_fn(pred, y).item() --> loss값을 받기 위해서는 item으로 접근해야 하는 것으로 보인다.
Epochs
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!")
식별하기 쉽게 print문을 작성하고 각 epoch에 학습 결과를 확인한다.
torch.save(model.state_dict(), "model.pth")
print("Saved PyTorch Model State to model.pth")
~/model.pth 저장
model = NeuralNetwork()
model.load_state_dict(torch.load("model.pth"))
keras callback checkpoint와 마찬가지로
일단 Model object를 생성한 후
model.load_state_dict를 통해 모델을 불러온다.
정상적으로 모델을 불러오면 다음의 메세지를 출력한다.
<All keys matched successfully>
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}"')
torch.cuda.is_available()
class Model(nn.Module):
def __init__(self):
super().__init__()
pass
def forward(self, x):
return logits
model = Model().to(device) # device is 'cuda' or 'cpu'
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters())
def train(dataloader, model, loss_fn, optimizer):
model.train()
for X, y in dataloader:
X, y = X.to(device), y.to(device)
optimizer.zero_grad()
loss.backward()
optimizer.step()
def test(dataloader, model, loss_fn):
model.eval()
with torch.no_grad():
https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html
실습 파일 : https://colab.research.google.com/drive/1aEzGNj5XoVeH85ohLNf2y3vsi09CLvoc?usp=sharing