From 872947e867f1c3b8bedde165b44710016885077c Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Tue, 28 Mar 2023 20:58:08 +0200 Subject: [PATCH] QuickStart Model Tutorial Finished Finished up first neural network tutorial with pytorch --- .gitattributes | 1 + .gitignore | 4 ++ FashionLabeling_model.pth | 3 + README.md | 15 +++++ quickStart/FashionLabeler.py | 84 ++++++++++++++++++++++++ quickStart/TrainFashionLabeler.py | 105 ++++++++++++++++++++++++++++++ requirements.txt | 6 ++ working_install_test.py | 6 ++ 8 files changed, 224 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 FashionLabeling_model.pth create mode 100644 README.md create mode 100644 quickStart/FashionLabeler.py create mode 100644 quickStart/TrainFashionLabeler.py create mode 100644 requirements.txt create mode 100644 working_install_test.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ec4a626 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.pth filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2603ec8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +data +venv +.vscode + diff --git a/FashionLabeling_model.pth b/FashionLabeling_model.pth new file mode 100644 index 0000000..73549ab --- /dev/null +++ b/FashionLabeling_model.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a287252b3c4dbb9102b66a37ddf2a32f9b5b161fae621bc21cb4574aa397f7c6 +size 2680967 diff --git a/README.md b/README.md new file mode 100644 index 0000000..151421c --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Pytorch Tutorials +## Learning about pytorch + +![Pytorch logo](https://cdn.icon-icons.com/icons2/2699/PNG/512/pytorch_logo_icon_169823.png) + +![Neural network image](https://tikz.net/wp-content/uploads/2021/12/neural_networks-001.png) + + +### Resources + +[https://pytorch.org/docs/stable/index.html](https://pytorch.org/docs/stable/index.html) + +- **Following tutorials from:** +[pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html](https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html) + diff --git a/quickStart/FashionLabeler.py b/quickStart/FashionLabeler.py new file mode 100644 index 0000000..a68bcff --- /dev/null +++ b/quickStart/FashionLabeler.py @@ -0,0 +1,84 @@ +import torch +import random +from torch import nn +from torch.utils.data import DataLoader +from torchvision import datasets +from torchvision.transforms import ToTensor + +# Download training data from open datasets +training_data = datasets.FashionMNIST( + root="data", + train=True, + download=True, + transform=ToTensor(), +) + +# Download test data from open datasets +test_data = datasets.FashionMNIST( + root="data", + train=False, + download=True, + transform=ToTensor(), +) + +batch_size = 64 + +# Create data loaders. +train_dataloader = DataLoader(training_data, batch_size=batch_size) +test_dataloader = DataLoader(test_data, batch_size=batch_size) + +for X, y in test_dataloader: + print(f"Shape of X [N, C, H, W]: {X.shape}") + print(f"Shape of y: {y.shape} {y.dtype}") + break + + +# Get cpu or gpu device for training +device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu" + +print(f"Using {device} device") + +# Define model +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.load_state_dict(torch.load("FashionLabeling_model.pth")) + +classes = [ + "T-shirt/top", + "Trouser", + "Pullover", + "Dress", + "Coat", + "Sandal", + "Shirt", + "Sneaker", + "Bag", + "Ankle boot" +] + + +model.eval() +# pick a random datapoint and test the model with it. +data = random.choice(test_data) +x, y = data[0] , data[1] + +with torch.no_grad(): + pred = model(x) + predicted, actual = classes[pred[0].argmax(0)], classes[y] + print(f'Predicted: "{predicted}", Actual: "{actual}"') + diff --git a/quickStart/TrainFashionLabeler.py b/quickStart/TrainFashionLabeler.py new file mode 100644 index 0000000..2f2d135 --- /dev/null +++ b/quickStart/TrainFashionLabeler.py @@ -0,0 +1,105 @@ +import torch +from torch import nn +from torch.utils.data import DataLoader +from torchvision import datasets +from torchvision.transforms import ToTensor + +# Download training data from open datasets +training_data = datasets.FashionMNIST( + root="data", + train=True, + download=True, + transform=ToTensor(), +) + +# Download test data from open datasets +test_data = datasets.FashionMNIST( + root="data", + train=False, + download=True, + transform=ToTensor(), +) + +batch_size = 64 + +# Create data loaders. +train_dataloader = DataLoader(training_data, batch_size=batch_size) +test_dataloader = DataLoader(test_data, batch_size=batch_size) + +for X, y in test_dataloader: + print(f"Shape of X [N, C, H, W]: {X.shape}") + print(f"Shape of y: {y.shape} {y.dtype}") + break + + +# Get cpu or gpu device for training +device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu" + +print(f"Using {device} device") + +# Define model +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().to(device=device) +print(model) +loss_fn = nn.CrossEntropyLoss() +optimizer = torch.optim.SGD(model.parameters(), lr=1e-3) + +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) + + # Compute prediction error + pred = model(X) + loss = loss_fn(pred, y) + + # Backpropegation + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if batch % 100 == 0: + loss, current = loss.item(), (batch + 1) * len(X) + print(f"loss: {loss:>7f} [{current:>5d}|{size:>5d}]") + +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") + +epochs = 40 +for t in range(epochs): + print(f"Epoch {t+1}\n-------------------------------") + train(train_dataloader, model, loss_fn=loss_fn, optimizer=optimizer) + test(test_dataloader, model, loss_fn=loss_fn) +print("Done!") + + +torch.save(model.state_dict(), "model.pth") +print("Saved PyTorch Model State to model.pth") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b1743b2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +--index-url https://download.pytorch.org/whl/cu117 +torch +--index-url https://download.pytorch.org/whl/cu117 +torchvision +--index-url https://download.pytorch.org/whl/cu117 +torchaudio \ No newline at end of file diff --git a/working_install_test.py b/working_install_test.py new file mode 100644 index 0000000..83c8c2c --- /dev/null +++ b/working_install_test.py @@ -0,0 +1,6 @@ +import torch + +x = torch.rand(5,3) +print("Random Tensor data: ", x) + +print("Cuda available: ", torch.cuda.is_available())