1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| import torch import torch.nn.functional as F import torchvision.datasets as datasets import torchvision.transforms as transforms from torch import nn, optim from torch.utils.data import DataLoader from tqdm import tqdm from torch.utils.data import random_split import pytorch_lightning as pl class NN(pl.LightningModule): def __init__(self, input_size, num_classes): super().__init__() self.fc1 = nn.Linear(input_size, 50) self.fc2 = nn.Linear(50, num_classes) self.loss_fn = nn.CrossEntropyLoss()
def forward(self, x): x = F.relu(self.fc1(x)) x = self.fc2(x) return x def training_step(self, batch, batch_idx): loss, scores, y = self._common_step(batch, batch_idx) self.log("train_loss", loss) return loss def validation_step(self, batch, batch_idx): loss, scores, y = self._common_step(batch, batch_idx) self.log("val_loss", loss) return loss def test_step(self, batch, batch_idx): loss, scores, y = self._common_step(batch, batch_idx) self.log("test_loss", loss) return loss def _common_step(self, batch, batch_idx): x, y = batch x = x.reshape(x.size(0), -1) scores = self.forward(x) loss = self.loss_fn(scores, y) return loss, scores, y def predict_step(self, batch, batch_idx): x, y = batch x = x.reshape(x.size(0), -1) scores = self.forward(x) preds = torch.argmax(scores, dim=1) return preds
def configure_optimizers(self): return optim.Adam(self.parameters(), lr=0.001)
input_size = 784 num_classes = 10 learning_rate = 0.001 batch_size = 64 num_epochs = 1
entire_dataset = datasets.MNIST( root="dataset/", train=True, transform=transforms.ToTensor(), download=False ) train_ds, val_ds = random_split(entire_dataset, [50000, 10000]) test_ds = datasets.MNIST( root="dataset/", train=False, transform=transforms.ToTensor(), download=False ) train_loader = DataLoader(dataset=train_ds, batch_size=batch_size, num_workers=0, shuffle=True) val_loader = DataLoader(dataset=val_ds, batch_size=batch_size, num_workers=0, shuffle=False) test_loader = DataLoader(dataset=test_ds, batch_size=batch_size, num_workers=0, shuffle=False)
for (images, labels) in train_loader: print(images.shape, labels.shape) break
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = NN(input_size=input_size, num_classes=num_classes).to(device)
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
trainer = pl.Trainer(accelerator="auto", devices="auto", min_epochs=1, max_epochs=3, precision=16)
trainer.fit(model=model, train_dataloaders=train_loader, val_dataloaders=val_loader) trainer.validate(model=model, dataloaders=val_loader) trainer.test(model=model, dataloaders=test_loader)
def check_accuracy(loader, model): num_correct = 0 num_samples = 0 model.eval()
with torch.no_grad(): for x, y in loader:
x = x.to(device=device) y = y.to(device=device)
x = x.reshape(x.shape[0], -1)
scores = model(x) _, predictions = scores.max(1)
num_correct += (predictions == y).sum()
num_samples += predictions.size(0)
model.train() return num_correct / num_samples
model.to(device)
print(f"Accuracy on training set: {check_accuracy(train_loader, model)*100:.2f}")
print(f"Accuracy on validation set: {check_accuracy(val_loader, model)*100:.2f}")
print(f"Accuracy on test set: {check_accuracy(test_loader, model)*100:.2f}")
|