Skip to content

Created mnist_classifier.py - Classifying MNIST dataset using a modified AlexNet #12325

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

Closed
wants to merge 6 commits into from
Closed
Changes from 2 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
168 changes: 168 additions & 0 deletions computer_vision/mnist_classifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
"""
This program is a MNIST classifier using AlexNet. It accepts three parameters provided as a command line input.

Check failure on line 2 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

computer_vision/mnist_classifier.py:2:89: E501 Line too long (112 > 88)

Check failure on line 2 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W291)

computer_vision/mnist_classifier.py:2:112: W291 Trailing whitespace
The first two inputs are two digits between 0-9 which are used to train and test the classifier and the third

Check failure on line 3 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

computer_vision/mnist_classifier.py:3:89: E501 Line too long (110 > 88)

Check failure on line 3 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W291)

computer_vision/mnist_classifier.py:3:110: W291 Trailing whitespace
parameter controls the number of training epochs.
Syntax: python program.py <number> <number> <number>

For example, to train and test AlexNet with 1 and 2 MNIST samples with 4 training epochs, the command line input should be:

Check failure on line 7 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

computer_vision/mnist_classifier.py:7:89: E501 Line too long (123 > 88)
python program.py 1 2 4

"""


import sys
import torch
import torch.nn as nn

Check failure on line 15 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (PLR0402)

computer_vision/mnist_classifier.py:15:8: PLR0402 Use `from torch import nn` in lieu of alias
import torchvision.datasets as dset
import torchvision.transforms as transforms

Check failure on line 17 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (PLR0402)

computer_vision/mnist_classifier.py:17:8: PLR0402 Use `from torchvision import transforms` in lieu of alias
from torch.autograd import Variable
import torch.nn.functional as F

Check failure on line 19 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (N812)

computer_vision/mnist_classifier.py:19:8: N812 Lowercase `functional` imported as non-lowercase `F`
import torch.optim as optim

Check failure on line 20 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (PLR0402)

computer_vision/mnist_classifier.py:20:8: PLR0402 Use `from torch import optim` in lieu of alias


class AlexNet(nn.Module):

Check failure on line 23 in computer_vision/mnist_classifier.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

computer_vision/mnist_classifier.py:13:1: I001 Import block is un-sorted or un-formatted
def __init__(self, num=10):
super(AlexNet, self).__init__()
self.feature = nn.Sequential(
# Define feature extractor here...
nn.Conv2d(1, 32, kernel_size=5, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(64, 96, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(96, 64, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(64, 32, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=1)
)

self.classifier = nn.Sequential(
# Define classifier here...
nn.Dropout(),
nn.Linear(32*12*12, 2048),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(2048, 1024),
nn.ReLU(inplace=True),
nn.Linear(1024, 10)
)

def forward(self, x):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: forward. If the function does not return a value, please provide the type hint as: def function() -> None:

As there is no test file in this pull request nor any test function or class in the file computer_vision/mnist_classifier.py, please provide doctest for the function forward

Please provide type hint for the parameter: x

Please provide descriptive name for the parameter: x

# define forward network 'x' that combines feature extractor and classifier
x = self.feature(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x


def load_subset(full_train_set, full_test_set, label_one, label_two):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide return type hint for the function: load_subset. If the function does not return a value, please provide the type hint as: def function() -> None:

As there is no test file in this pull request nor any test function or class in the file computer_vision/mnist_classifier.py, please provide doctest for the function load_subset

Please provide type hint for the parameter: full_train_set

Please provide type hint for the parameter: full_test_set

Please provide type hint for the parameter: label_one

Please provide type hint for the parameter: label_two

# Sample the correct train labels
train_set = []
data_lim = 20000
for data in full_train_set:
if data_lim>0:
data_lim-=1
if data[1]==label_one or data[1]==label_two:
train_set.append(data)
else:
break

test_set = []
data_lim = 1000
for data in full_test_set:
if data_lim>0:
data_lim-=1
if data[1]==label_one or data[1]==label_two:
test_set.append(data)
else:
break

return train_set, test_set

def train(model,optimizer,train_loader,epoch):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
if torch.cuda.is_available():
data, target = data.cuda(), target.cuda()
data, target = Variable(data), Variable(target)
optimizer.zero_grad()
output = model(data)
loss = F.cross_entropy(output, target)
loss.backward()
optimizer.step()

def test(model,test_loader):
model.eval()
test_loss = 0
correct = 0
for data, target in test_loader:
if torch.cuda.is_available():
data, target = data.cuda(), target.cuda()
with torch.no_grad():
data, target = Variable(data), Variable(target)
output = model(data)
test_loss += F.cross_entropy(output, target, reduction='sum').item()#size_average=False
pred = output.data.max(1, keepdim=True)[1] # get the index of the max log-probability
correct += pred.eq(target.data.view_as(pred)).long().cpu().sum()

test_loss /= len(test_loader.dataset)
acc=100. * float(correct.to(torch.device('cpu')).numpy())
test_accuracy = (acc / len(test_loader.dataset))
return test_accuracy


""" Start to call """

if __name__ == '__main__':

if len(sys.argv) == 3:
print("Usage: python assignment.py <number> <number>")
sys.exit(1)

input_data_one = sys.argv[1].strip()
input_data_two = sys.argv[2].strip()
epochs = sys.argv[3].strip()

""" Call to function that will perform the computation. """
if input_data_one.isdigit() and input_data_two.isdigit() and epochs.isdigit():

label_one = int(input_data_one)
label_two = int(input_data_two)
epochs = int(epochs)

if label_one!=label_two and 0<=label_one<=9 and 0<=label_two<=9:
torch.manual_seed(42)
# Load MNIST dataset
trans = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (1.0,))])
full_train_set = dset.MNIST(root='./data', train=True, transform=trans, download=True)
full_test_set = dset.MNIST(root='./data', train=False, transform=trans)
batch_size = 16
# Get final train and test sets
train_set, test_set = load_subset(full_train_set,full_test_set,label_one,label_two)

train_loader = torch.utils.data.DataLoader(dataset=train_set,batch_size=batch_size,shuffle=False)
test_loader = torch.utils.data.DataLoader(dataset=test_set,batch_size=batch_size,shuffle=False)

model = AlexNet()
if torch.cuda.is_available():
model.cuda()

optimizer = optim.SGD(model.parameters(), lr=0.01)

for epoch in range(1, epochs+1):
train(model,optimizer,train_loader,epoch)
accuracy = test(model,test_loader)

print(round(accuracy,2))


else:
print("Invalid input")
else:
print("Invalid input")


""" End to call """
Loading