Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor training loop from script to class #31

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
# evals
# evals

This project contains a PyTorch implementation for training and evaluating a simple neural network on the MNIST dataset.

## ModelTrainer class

The `ModelTrainer` class is used to train and evaluate the model. Here is how you can use it:

```python
from main import ModelTrainer

# Create an instance of ModelTrainer
trainer = ModelTrainer()

# Run the training and evaluation process
trainer.run()
```

The `ModelTrainer` class has the following methods:

- `load_data()`: Loads the MNIST dataset and applies the necessary transformations.
- `define_model()`: Defines the model architecture.
- `train_model()`: Trains the model on the MNIST dataset.
- `evaluate()`: Evaluates the model performance on the test dataset.
- `run()`: Runs the entire process (data loading, model definition, training, and evaluation).

## Saving and Loading the Model

After training, the model's parameters are saved to a file named "mnist_model.pth". You can load the model parameters using the `torch.load()` function:

```python
model.load_state_dict(torch.load("mnist_model.pth"))
```
9 changes: 4 additions & 5 deletions src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
from PIL import Image
import torch
from torchvision import transforms
from main import Net # Importing Net class from main.py
from main import ModelTrainer # Importing ModelTrainer class from main.py

# Load the model
model = Net()
model.load_state_dict(torch.load("mnist_model.pth"))
model.eval()
# Create an instance of ModelTrainer and load the model
trainer = ModelTrainer()
model = trainer.load_model("mnist_model.pth")

# Transform used for preprocessing the image
transform = transforms.Compose([
Expand Down
117 changes: 77 additions & 40 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,80 @@
from torch.utils.data import DataLoader
import numpy as np

# Step 1: Load MNIST Data and Preprocess
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])

trainset = datasets.MNIST('.', download=True, train=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=64, shuffle=True)

# Step 2: Define the PyTorch Model
class Net(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(28 * 28, 128)
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 10)

def forward(self, x):
x = x.view(-1, 28 * 28)
x = nn.functional.relu(self.fc1(x))
x = nn.functional.relu(self.fc2(x))
x = self.fc3(x)
return nn.functional.log_softmax(x, dim=1)

# Step 3: Train the Model
model = Net()
optimizer = optim.SGD(model.parameters(), lr=0.01)
criterion = nn.NLLLoss()

# Training loop
epochs = 3
for epoch in range(epochs):
for images, labels in trainloader:
optimizer.zero_grad()
output = model(images)
loss = criterion(output, labels)
loss.backward()
optimizer.step()

torch.save(model.state_dict(), "mnist_model.pth")
class ModelTrainer:
def __init__(self, epochs=3, lr=0.01, batch_size=64):
self.epochs = epochs
self.lr = lr
self.batch_size = batch_size
self.model = None
self.optimizer = None
self.criterion = nn.NLLLoss()
self.trainloader = None

def load_data(self):
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])

trainset = datasets.MNIST('.', download=True, train=True, transform=transform)
self.trainloader = DataLoader(trainset, batch_size=self.batch_size, shuffle=True)

def define_model(self):
class Net(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(28 * 28, 128)
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 10)

def forward(self, x):
x = x.view(-1, 28 * 28)
x = nn.functional.relu(self.fc1(x))
x = nn.functional.relu(self.fc2(x))
x = self.fc3(x)
return nn.functional.log_softmax(x, dim=1)

self.model = Net()
self.optimizer = optim.SGD(self.model.parameters(), lr=self.lr)

def train_model(self):
for epoch in range(self.epochs):
for images, labels in self.trainloader:
self.optimizer.zero_grad()
output = self.model(images)
loss = self.criterion(output, labels)
loss.backward()
self.optimizer.step()

def evaluate(self):
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])

testset = datasets.MNIST('.', download=True, train=False, transform=transform)
testloader = DataLoader(testset, batch_size=self.batch_size, shuffle=True)

correct = 0
total = 0

with torch.no_grad():
for images, labels in testloader:
output = self.model(images)
_, predicted = torch.max(output.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()

accuracy = 100 * correct / total
print('Accuracy of the model on the test images: %d%%' % accuracy)

def run(self):
self.load_data()
self.define_model()
self.train_model()
self.evaluate()
torch.save(self.model.state_dict(), "mnist_model.pth")

trainer = ModelTrainer()
trainer.run()