{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "id": "EZay5pyZMWBg" }, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.optim as optim\n", "from torchvision import datasets, transforms\n", "from torch.utils.data import DataLoader\n", "\n", "# Load the dataset\n", "transform = transforms.Compose([\n", " transforms.ToTensor() # Automatically converts to tensor and scales to [0, 1]\n", "])\n", "train_dataset = datasets.FashionMNIST(root='./data', train=True, download=True, transform=transform)\n", "test_dataset = datasets.FashionMNIST(root='./data', train=False, download=True, transform=transform)\n", "\n", "train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)\n", "test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)\n", "\n", "# Define the model\n", "class FashionMNISTModel(nn.Module):\n", " def __init__(self):\n", " super(FashionMNISTModel, self).__init__()\n", " self.flatten = nn.Flatten()\n", " self.linear_relu_stack = nn.Sequential(\n", " nn.Linear(28*28, 128),\n", " nn.ReLU(),\n", " nn.Linear(128, 10),\n", " nn.LogSoftmax(dim=1)\n", " )\n", "\n", " def forward(self, x):\n", " x = self.flatten(x)\n", " logits = self.linear_relu_stack(x)\n", " return logits\n", "\n", "model = FashionMNISTModel()\n", "\n", "# Define the loss function and optimizer\n", "loss_function = nn.NLLLoss()\n", "optimizer = optim.Adam(model.parameters())\n", "\n", "# Train the model\n", "def train(dataloader, model, loss_fn, optimizer):\n", " size = len(dataloader.dataset)\n", " model.train()\n", " for batch, (X, y) in enumerate(dataloader):\n", " # Compute prediction and loss\n", " pred = model(X)\n", " loss = loss_fn(pred, y)\n", "\n", " # Backpropagation\n", " optimizer.zero_grad()\n", " loss.backward()\n", " optimizer.step()\n", " if batch % 100 == 0:\n", " loss, current = loss.item(), batch * len(X)\n", " print(f\"loss: {loss:>7f} [{current:>5d}/{size:>5d}]\")\n", "\n", "# Training process\n", "epochs = 5\n", "for t in range(epochs):\n", " print(f\"Epoch {t+1}\\n-------------------------------\")\n", " train(train_loader, model, loss_function, optimizer)\n", "print(\"Done!\")\n" ] }, { "cell_type": "code", "source": [ "# Function to test the model\n", "def test(dataloader, model):\n", " size = len(dataloader.dataset)\n", " num_batches = len(dataloader)\n", " model.eval() # Set the model to evaluation mode\n", " test_loss, correct = 0, 0\n", " with torch.no_grad():\n", " for X, y in dataloader:\n", " pred = model(X)\n", " test_loss += loss_function(pred, y).item()\n", " correct += (pred.argmax(1) == y).type(torch.float).sum().item()\n", " test_loss /= num_batches\n", " correct /= size\n", " print(f\"Test Error: \\n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \\n\")\n", "\n", "# Evaluate the model\n", "test(test_loader, model)\n" ], "metadata": { "id": "ozzKgn7_O_66" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# CHECK SINGLE PREDICTION AND PLOT\n", "import matplotlib.pyplot as plt\n", "\n", "def predict_single_image(image, label, model):\n", " # Set the model to evaluation mode\n", " model.eval()\n", "\n", " # Image needs to be unsqueezed as the model expects a batch dimension\n", " image = image.unsqueeze(0)\n", "\n", " with torch.no_grad():\n", " prediction = model(image)\n", " print(prediction)\n", " predicted_label = prediction.argmax(1).item()\n", "\n", " # Display the image and predictions\n", " plt.imshow(image.squeeze(), cmap='gray')\n", " plt.title(f'Predicted: {predicted_label}, Actual: {label}')\n", " plt.show()\n", "\n", " return predicted_label\n", "\n", "# Choose an image from the test set\n", "image, label = test_dataset[0] # Change index to test different images\n", "\n", "# Predict the class for the chosen image\n", "predicted_label = predict_single_image(image, label, model)\n", "print(f\"The model predicted {predicted_label}, and the actual label is {label}.\")\n" ], "metadata": { "id": "HNZ-FF6NPSTe" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# EARLY STOPPING VERSION\n", "import torch\n", "import torch.nn as nn\n", "import torch.optim as optim\n", "from torchvision import datasets, transforms\n", "from torch.utils.data import DataLoader\n", "\n", "# Load the dataset\n", "transform = transforms.Compose([\n", " transforms.ToTensor() # Automatically converts to tensor and scales to [0, 1]\n", "])\n", "train_dataset = datasets.FashionMNIST(root='./data', train=True, download=True, transform=transform)\n", "test_dataset = datasets.FashionMNIST(root='./data', train=False, download=True, transform=transform)\n", "\n", "train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)\n", "test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)\n", "\n", "# Define the model\n", "class FashionMNISTModel(nn.Module):\n", " def __init__(self):\n", " super(FashionMNISTModel, self).__init__()\n", " self.flatten = nn.Flatten()\n", " self.linear_relu_stack = nn.Sequential(\n", " nn.Linear(28*28, 128),\n", " nn.ReLU(),\n", " nn.Linear(128, 10),\n", " nn.LogSoftmax(dim=1)\n", " )\n", "\n", " def forward(self, x):\n", " x = self.flatten(x)\n", " logits = self.linear_relu_stack(x)\n", " return logits\n", "\n", "model = FashionMNISTModel()\n", "\n", "# Define the loss function and optimizer\n", "loss_function = nn.NLLLoss()\n", "optimizer = optim.Adam(model.parameters())\n", "\n", "# Function to calculate accuracy\n", "def get_accuracy(pred, labels):\n", " _, predictions = torch.max(pred, 1)\n", " correct = (predictions == labels).float().sum()\n", " accuracy = correct / labels.shape[0]\n", " return accuracy\n", "\n", "# Train the model with accuracy reporting\n", "def train(dataloader, model, loss_fn, optimizer):\n", " size = len(dataloader.dataset)\n", " num_batches = len(dataloader)\n", " total_loss, total_accuracy = 0, 0\n", "\n", " model.train()\n", " for batch, (X, y) in enumerate(dataloader):\n", " # Compute prediction and loss\n", " pred = model(X)\n", " loss = loss_fn(pred, y)\n", " accuracy = get_accuracy(pred, y)\n", "\n", " # Backpropagation\n", " optimizer.zero_grad()\n", " loss.backward()\n", " optimizer.step()\n", "\n", " total_loss += loss.item()\n", " total_accuracy += accuracy.item()\n", "\n", " if batch % 100 == 0:\n", " current = batch * len(X)\n", " avg_loss = total_loss / (batch + 1)\n", " avg_accuracy = total_accuracy / (batch + 1) * 100\n", " print(f\"Batch {batch}, Loss: {avg_loss:>7f}, Accuracy: {avg_accuracy:>0.2f}% [{current:>5d}/{size:>5d}]\")\n", "\n", " # Early stopping condition\n", " if avg_accuracy >= 95:\n", " print(\"Reached 95% accuracy, stopping training.\")\n", " return True # Stop training\n", "\n", "# Training process\n", "epochs = 50\n", "for t in range(epochs):\n", " print(f\"Epoch {t+1}\\n-------------------------------\")\n", " if train(train_loader, model, loss_function, optimizer): # Check for the early stopping signal\n", " print(\"Early stopping triggered.\")\n", " break\n", "print(\"Done!\")\n" ], "metadata": { "id": "Ve9Y_VI-yaCq" }, "execution_count": null, "outputs": [] } ] }