From 5b185ffe992029b6c4e94c3d23ec0dad75cb6a75 Mon Sep 17 00:00:00 2001 From: Argho Chakraborty Date: Wed, 30 Oct 2024 10:24:02 +0530 Subject: [PATCH 1/6] Create MNIST_Classifier.py Python program using the provided template to train and test a MNIST dataset using a modified AlexNet model. The program should accept three integers as command line input. First two integers define the labels of the two-class classification and third integer represents the number of epochs for training. --- computer_vision/MNIST_Classifier.py | 168 ++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 computer_vision/MNIST_Classifier.py diff --git a/computer_vision/MNIST_Classifier.py b/computer_vision/MNIST_Classifier.py new file mode 100644 index 000000000000..70015df76dec --- /dev/null +++ b/computer_vision/MNIST_Classifier.py @@ -0,0 +1,168 @@ +""" +This program is a MNIST classifier using AlexNet. It accepts three parameters provided as a command line input. +The first two inputs are two digits between 0-9 which are used to train and test the classifier and the third +parameter controls the number of training epochs. +Syntax: python program.py + +For example, to train and test AlexNet with 1 and 2 MNIST samples with 4 training epochs, the command line input should be: +python program.py 1 2 4 + +""" + + +import sys +import torch +import torch.nn as nn +import torchvision.datasets as dset +import torchvision.transforms as transforms +from torch.autograd import Variable +import torch.nn.functional as F +import torch.optim as optim + + +class AlexNet(nn.Module): + 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): + # 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): + # 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 ") + 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 """ From d45f819214006d4a57b0be1ec0e0305abd61ed60 Mon Sep 17 00:00:00 2001 From: Argho Chakraborty Date: Wed, 30 Oct 2024 10:34:01 +0530 Subject: [PATCH 2/6] Rename MNIST_Classifier.py to mnist_classifier.py Uppercase to lowercase rename. --- computer_vision/{MNIST_Classifier.py => mnist_classifier.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename computer_vision/{MNIST_Classifier.py => mnist_classifier.py} (100%) diff --git a/computer_vision/MNIST_Classifier.py b/computer_vision/mnist_classifier.py similarity index 100% rename from computer_vision/MNIST_Classifier.py rename to computer_vision/mnist_classifier.py From 3eda592631efab29ee4cdecf7dd7c4ceb44cb220 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 05:05:33 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- computer_vision/mnist_classifier.py | 104 ++++++++++++++++------------ 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/computer_vision/mnist_classifier.py b/computer_vision/mnist_classifier.py index 70015df76dec..7f33443af0e4 100644 --- a/computer_vision/mnist_classifier.py +++ b/computer_vision/mnist_classifier.py @@ -1,6 +1,6 @@ """ -This program is a MNIST classifier using AlexNet. It accepts three parameters provided as a command line input. -The first two inputs are two digits between 0-9 which are used to train and test the classifier and the third +This program is a MNIST classifier using AlexNet. It accepts three parameters provided as a command line input. +The first two inputs are two digits between 0-9 which are used to train and test the classifier and the third parameter controls the number of training epochs. Syntax: python program.py @@ -9,7 +9,6 @@ """ - import sys import torch import torch.nn as nn @@ -20,7 +19,7 @@ import torch.optim as optim -class AlexNet(nn.Module): +class AlexNet(nn.Module): def __init__(self, num=10): super(AlexNet, self).__init__() self.feature = nn.Sequential( @@ -36,20 +35,20 @@ def __init__(self, num=10): nn.ReLU(inplace=True), nn.Conv2d(64, 32, kernel_size=3, padding=1), nn.ReLU(inplace=True), - nn.MaxPool2d(kernel_size=2, stride=1) + nn.MaxPool2d(kernel_size=2, stride=1), ) self.classifier = nn.Sequential( # Define classifier here... nn.Dropout(), - nn.Linear(32*12*12, 2048), + nn.Linear(32 * 12 * 12, 2048), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(2048, 1024), nn.ReLU(inplace=True), - nn.Linear(1024, 10) + nn.Linear(1024, 10), ) - + def forward(self, x): # define forward network 'x' that combines feature extractor and classifier x = self.feature(x) @@ -63,9 +62,9 @@ def load_subset(full_train_set, full_test_set, label_one, label_two): 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: + if data_lim > 0: + data_lim -= 1 + if data[1] == label_one or data[1] == label_two: train_set.append(data) else: break @@ -73,16 +72,17 @@ def load_subset(full_train_set, full_test_set, label_one, label_two): 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: + 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): + +def train(model, optimizer, train_loader, epoch): model.train() for batch_idx, (data, target) in enumerate(train_loader): if torch.cuda.is_available(): @@ -94,7 +94,8 @@ def train(model,optimizer,train_loader,epoch): loss.backward() optimizer.step() -def test(model,test_loader): + +def test(model, test_loader): model.eval() test_loss = 0 correct = 0 @@ -104,20 +105,23 @@ def test(model,test_loader): 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 + 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)) + acc = 100.0 * float(correct.to(torch.device("cpu")).numpy()) + test_accuracy = acc / len(test_loader.dataset) return test_accuracy """ Start to call """ -if __name__ == '__main__': - +if __name__ == "__main__": if len(sys.argv) == 3: print("Usage: python assignment.py ") sys.exit(1) @@ -125,44 +129,52 @@ def test(model,test_loader): 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: + + 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) + 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) + 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)) - - + + 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") + print("Invalid input") else: print("Invalid input") - - + + """ End to call """ From 96af3105a51b54809ef0c26507c14b5b7025ea3a Mon Sep 17 00:00:00 2001 From: Argho Chakraborty Date: Wed, 30 Oct 2024 11:54:04 +0530 Subject: [PATCH 4/6] Update mnist_classifier.py modified the file --- computer_vision/mnist_classifier.py | 34 +++++++++++++---------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/computer_vision/mnist_classifier.py b/computer_vision/mnist_classifier.py index 7f33443af0e4..f782b17fc1a7 100644 --- a/computer_vision/mnist_classifier.py +++ b/computer_vision/mnist_classifier.py @@ -1,27 +1,25 @@ """ -This program is a MNIST classifier using AlexNet. It accepts three parameters provided as a command line input. -The first two inputs are two digits between 0-9 which are used to train and test the classifier and the third -parameter controls the number of training epochs. -Syntax: python program.py +This program is a MNIST classifier using AlexNet. -For example, to train and test AlexNet with 1 and 2 MNIST samples with 4 training epochs, the command line input should be: +For example, to train and test AlexNet with 1 and 2 MNIST samples with 4 training epochs. +The command line input should be: python program.py 1 2 4 """ import sys import torch -import torch.nn as nn +import torch.nn import torchvision.datasets as dset -import torchvision.transforms as transforms +import torchvision.transforms from torch.autograd import Variable -import torch.nn.functional as F -import torch.optim as optim +import torch.nn.functional as f +import torch.optim class AlexNet(nn.Module): - def __init__(self, num=10): - super(AlexNet, self).__init__() + def __init__(self, num): + super().__init__() self.feature = nn.Sequential( # Define feature extractor here... nn.Conv2d(1, 32, kernel_size=5, stride=1, padding=1), @@ -84,13 +82,13 @@ def load_subset(full_train_set, full_test_set, label_one, label_two): def train(model, optimizer, train_loader, epoch): model.train() - for batch_idx, (data, target) in enumerate(train_loader): + for 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 = f.cross_entropy(output, target) loss.backward() optimizer.step() @@ -105,12 +103,10 @@ def test(model, test_loader): 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 + 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) From 488d56cf63f0d4b35799a087e1999a4d0030cad8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 06:24:38 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- computer_vision/mnist_classifier.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/computer_vision/mnist_classifier.py b/computer_vision/mnist_classifier.py index f782b17fc1a7..7904381bb960 100644 --- a/computer_vision/mnist_classifier.py +++ b/computer_vision/mnist_classifier.py @@ -1,5 +1,5 @@ """ -This program is a MNIST classifier using AlexNet. +This program is a MNIST classifier using AlexNet. For example, to train and test AlexNet with 1 and 2 MNIST samples with 4 training epochs. The command line input should be: @@ -103,9 +103,9 @@ def test(model, test_loader): with torch.no_grad(): data, target = Variable(data), Variable(target) output = model(data) - test_loss += F.cross_entropy(output, target, reduction="sum").item() + test_loss += F.cross_entropy(output, target, reduction="sum").item() # size_average=False - pred = output.data.max(1, keepdim=True)[1] + 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() From d07977f6cfb27354d0a782bb5ed1b58f1078b7b0 Mon Sep 17 00:00:00 2001 From: Argho Chakraborty Date: Wed, 30 Oct 2024 12:11:37 +0530 Subject: [PATCH 6/6] Update mnist_classifier.py modified mnist_classifier.py --- computer_vision/mnist_classifier.py | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/computer_vision/mnist_classifier.py b/computer_vision/mnist_classifier.py index 7904381bb960..dcc7efb1e1f8 100644 --- a/computer_vision/mnist_classifier.py +++ b/computer_vision/mnist_classifier.py @@ -9,7 +9,7 @@ import sys import torch -import torch.nn +import torch.nn as n import torchvision.datasets as dset import torchvision.transforms from torch.autograd import Variable @@ -17,34 +17,34 @@ import torch.optim -class AlexNet(nn.Module): +class AlexNet(n.Module): def __init__(self, num): super().__init__() - self.feature = nn.Sequential( + self.feature = n.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), + n.Conv2d(1, 32, kernel_size=5, stride=1, padding=1), + n.ReLU(inplace=True), + n.Conv2d(32, 64, kernel_size=3, padding=1), + n.ReLU(inplace=True), + n.MaxPool2d(kernel_size=2, stride=2), + n.Conv2d(64, 96, kernel_size=3, padding=1), + n.ReLU(inplace=True), + n.Conv2d(96, 64, kernel_size=3, padding=1), + n.ReLU(inplace=True), + n.Conv2d(64, 32, kernel_size=3, padding=1), + n.ReLU(inplace=True), + n.MaxPool2d(kernel_size=2, stride=1), ) - self.classifier = nn.Sequential( + self.classifier = n.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), + n.Dropout(), + n.Linear(32 * 12 * 12, 2048), + n.ReLU(inplace=True), + n.Dropout(), + n.Linear(2048, 1024), + n.ReLU(inplace=True), + n.Linear(1024, 10), ) def forward(self, x):