mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-07-06 21:03:14 +02:00
feat: make code pep8 compliant
This commit is contained in:
parent
f0c02993d9
commit
e6693df39b
3
.gitignore
vendored
3
.gitignore
vendored
@ -462,3 +462,6 @@ TSWLatexianTemp*
|
|||||||
# option is specified. Footnotes are the stored in a file with suffix Notes.bib.
|
# option is specified. Footnotes are the stored in a file with suffix Notes.bib.
|
||||||
# Uncomment the next line to have this generated file ignored.
|
# Uncomment the next line to have this generated file ignored.
|
||||||
#*Notes.bib
|
#*Notes.bib
|
||||||
|
|
||||||
|
# MNSIT data
|
||||||
|
data/MNIST/raw
|
||||||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -5,6 +5,7 @@
|
|||||||
"mikoz.black-py",
|
"mikoz.black-py",
|
||||||
"james-yu.latex-workshop",
|
"james-yu.latex-workshop",
|
||||||
"kisstkondoros.vscode-gutter-preview",
|
"kisstkondoros.vscode-gutter-preview",
|
||||||
"streetsidesoftware.code-spell-checker"
|
"streetsidesoftware.code-spell-checker",
|
||||||
|
"wesbos.theme-cobalt2"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -5,8 +5,11 @@
|
|||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"dtype",
|
"dtype",
|
||||||
"loadtxt",
|
"loadtxt",
|
||||||
|
"MNIST",
|
||||||
"optim",
|
"optim",
|
||||||
"Xbatch",
|
"Xbatch",
|
||||||
"ybatch"
|
"ybatch"
|
||||||
]
|
],
|
||||||
|
"python.linting.pylintEnabled": true,
|
||||||
|
"python.linting.enabled": true
|
||||||
}
|
}
|
||||||
9
lab5/code/.pylintrc
Normal file
9
lab5/code/.pylintrc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[TYPECHECK]
|
||||||
|
|
||||||
|
# List of members which are set dynamically and missed by Pylint inference
|
||||||
|
# system, and so shouldn't trigger E1101 when accessed. (Module 'torch' has no 'max' member)
|
||||||
|
generated-members=numpy.*, torch.*
|
||||||
|
|
||||||
|
[DESIGN]
|
||||||
|
# Maximum number of statements in function / method body
|
||||||
|
max-statements=16
|
||||||
@ -1,92 +1,193 @@
|
|||||||
|
""" Implementation of a network analyzing MNIST dataset """
|
||||||
import torch
|
import torch
|
||||||
import torch.nn as nn
|
from torch import nn
|
||||||
import torch.optim as optim
|
from torch import optim
|
||||||
from torchvision import datasets, transforms
|
from torchvision import datasets, transforms
|
||||||
|
|
||||||
# Set random seed for reproducibility
|
|
||||||
torch.manual_seed(42)
|
|
||||||
|
|
||||||
# Define hyperparameters
|
def set_hyperparameters():
|
||||||
learning_rate = 0.001
|
""" sets hyperparameters used throughout the network """
|
||||||
batch_size = 64
|
return {
|
||||||
num_epochs = 10
|
"learning_rate": 0.001,
|
||||||
input_size = 28 * 28 # MNIST images are 28x28 pixels
|
"batch_size": 64,
|
||||||
hidden_size = 128
|
"num_epochs": 2,
|
||||||
num_classes = 10
|
"input_size": 28 * 28, # MNIST images are 28x28 pixels
|
||||||
|
"hidden_size": 128,
|
||||||
|
"num_classes": 10,
|
||||||
|
}
|
||||||
|
|
||||||
# Load MNIST dataset and apply transformations
|
|
||||||
train_dataset = datasets.MNIST(
|
|
||||||
root='./data', train=True, transform=transforms.ToTensor(), download=True
|
|
||||||
)
|
|
||||||
test_dataset = datasets.MNIST(
|
|
||||||
root='./data', train=False, transform=transforms.ToTensor(), download=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create data loaders
|
def load_datasets():
|
||||||
train_loader = torch.utils.data.DataLoader(
|
""" Loads train and test dataset from MNIST """
|
||||||
dataset=train_dataset, batch_size=batch_size, shuffle=True
|
train_dataset = datasets.MNIST(
|
||||||
)
|
root="./data", train=True, transform=transforms.ToTensor(), download=True
|
||||||
test_loader = torch.utils.data.DataLoader(
|
)
|
||||||
dataset=test_dataset, batch_size=batch_size, shuffle=False
|
test_dataset = datasets.MNIST(
|
||||||
)
|
root="./data", train=False, transform=transforms.ToTensor(), download=True
|
||||||
|
)
|
||||||
|
return train_dataset, test_dataset
|
||||||
|
|
||||||
# Define the multilayer perceptron model
|
|
||||||
model = nn.Sequential(
|
|
||||||
nn.Linear(input_size, hidden_size),
|
|
||||||
nn.ReLU(),
|
|
||||||
nn.Linear(hidden_size, num_classes)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Loss function
|
def create_data_loaders(train_dataset, test_dataset, hyperparameters):
|
||||||
criterion = nn.CrossEntropyLoss()
|
""" Create train and test data loaders """
|
||||||
|
train_loader = torch.utils.data.DataLoader(
|
||||||
|
dataset=train_dataset, batch_size=hyperparameters["batch_size"], shuffle=True
|
||||||
|
)
|
||||||
|
test_loader = torch.utils.data.DataLoader(
|
||||||
|
dataset=test_dataset, batch_size=hyperparameters["batch_size"], shuffle=False
|
||||||
|
)
|
||||||
|
return train_loader, test_loader
|
||||||
|
|
||||||
# Optimizer
|
|
||||||
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
|
|
||||||
|
|
||||||
# Training loop
|
def define_model(hyperparameters):
|
||||||
for epoch in range(num_epochs):
|
""" Define the multilayer perceptron training_parameters['model'] """
|
||||||
for batch_idx, (data, targets) in enumerate(train_loader):
|
model = nn.Sequential(
|
||||||
# Reshape the input data
|
nn.Linear(hyperparameters["input_size"],
|
||||||
data = data.view(data.size(0), -1)
|
hyperparameters["hidden_size"]),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Linear(hyperparameters["hidden_size"],
|
||||||
|
hyperparameters["num_classes"]),
|
||||||
|
)
|
||||||
|
return model
|
||||||
|
|
||||||
# Forward pass
|
|
||||||
outputs = model(data)
|
|
||||||
loss = criterion(outputs, targets)
|
|
||||||
|
|
||||||
# Backward pass and optimization
|
def initial_configuration():
|
||||||
optimizer.zero_grad()
|
"""
|
||||||
loss.backward()
|
Perform all operations needed for training network
|
||||||
optimizer.step()
|
"""
|
||||||
|
# Set random seed for reproducibility
|
||||||
|
torch.manual_seed(42)
|
||||||
|
hyperparameters = set_hyperparameters()
|
||||||
|
# Load MNIST dataset and apply transformations
|
||||||
|
train_dataset, test_dataset = load_datasets()
|
||||||
|
train_loader, test_loader = create_data_loaders(
|
||||||
|
train_dataset, test_dataset, hyperparameters
|
||||||
|
)
|
||||||
|
model = define_model(hyperparameters)
|
||||||
|
# Loss function
|
||||||
|
criterion = nn.CrossEntropyLoss()
|
||||||
|
# training_parameters['optimizer']
|
||||||
|
optimizer = optim.Adam(
|
||||||
|
model.parameters(), lr=hyperparameters["learning_rate"])
|
||||||
|
return hyperparameters, train_loader, test_loader, model, criterion, optimizer
|
||||||
|
|
||||||
# Print loss value for every learning step
|
|
||||||
if (batch_idx+1) % 100 == 0:
|
|
||||||
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{batch_idx+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
|
|
||||||
|
|
||||||
# Calculate accuracy on train set after each epoch
|
def single_train_iteration(
|
||||||
|
data, training_parameters, targets, batch_idx, epoch
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Train network for single batch
|
||||||
|
"""
|
||||||
|
# Reshape the input data
|
||||||
|
data = data.view(data.size(0), -1)
|
||||||
|
# Forward pass
|
||||||
|
outputs = training_parameters['model'](data)
|
||||||
|
loss = training_parameters['criterion'](outputs, targets)
|
||||||
|
# Backward pass and optimization
|
||||||
|
training_parameters['optimizer'].zero_grad()
|
||||||
|
loss.backward()
|
||||||
|
training_parameters['optimizer'].step()
|
||||||
|
# Print loss value for every learning step
|
||||||
|
if (batch_idx + 1) % 100 == 0:
|
||||||
|
print(
|
||||||
|
f'''
|
||||||
|
Epoch [{epoch+1}/{training_parameters['hyperparameters']["num_epochs"]}],
|
||||||
|
Step [{batch_idx+1}/ \
|
||||||
|
{len(training_parameters['loaders']['train_loader'])}],
|
||||||
|
Loss: {loss.item():.4f}
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
return data, training_parameters['optimizer']
|
||||||
|
|
||||||
|
|
||||||
|
def set_loaders(train_loader, test_loader):
|
||||||
|
"""
|
||||||
|
Put train and test loaders into one object
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
'train_loader': train_loader,
|
||||||
|
'test_loader': test_loader
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def set_training_parameters(hyperparameters, loaders, model, criterion, optimizer):
|
||||||
|
"""
|
||||||
|
Put all training parameters into one object
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
'hyperparameters': hyperparameters,
|
||||||
|
'loaders': {
|
||||||
|
'train_loader': loaders['train_loader'],
|
||||||
|
'test_loader': loaders['test_loader']
|
||||||
|
},
|
||||||
|
'model': model,
|
||||||
|
'criterion': criterion,
|
||||||
|
'optimizer': optimizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def training_loop(training_parameters):
|
||||||
|
"""
|
||||||
|
Train network for all epochs
|
||||||
|
"""
|
||||||
|
epochs_num = training_parameters["hyperparameters"]["num_epochs"]
|
||||||
|
# Training loop
|
||||||
|
for epoch in range(epochs_num):
|
||||||
|
for batch_idx, (data, targets) in enumerate(training_parameters['loaders']['train_loader']):
|
||||||
|
data, training_parameters['optimizer'] = single_train_iteration(
|
||||||
|
data, training_parameters, targets, batch_idx, epoch
|
||||||
|
)
|
||||||
|
calculate_accuracy_epoch(
|
||||||
|
training_parameters, epoch)
|
||||||
|
calculate_validation_set_accuracy(
|
||||||
|
training_parameters, epoch)
|
||||||
|
return epoch, training_parameters['loaders']['train_loader']
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_accuracy_epoch(training_parameters, epoch):
|
||||||
|
""" Calculate accuracy on train set after each epoch """
|
||||||
correct = 0
|
correct = 0
|
||||||
total = 0
|
total = 0
|
||||||
for data, targets in train_loader:
|
for data, targets in training_parameters['loaders']['train_loader']:
|
||||||
data = data.view(data.size(0), -1)
|
data = data.view(data.size(0), -1)
|
||||||
outputs = model(data)
|
outputs = training_parameters['model'](data)
|
||||||
_, predicted = torch.max(outputs.data, 1)
|
_, predicted = torch.max(outputs.data, 1)
|
||||||
total += targets.size(0)
|
total += targets.size(0)
|
||||||
correct += (predicted == targets).sum().item()
|
correct += (predicted == targets).sum().item()
|
||||||
|
|
||||||
train_accuracy = 100 * correct / total
|
train_accuracy = 100 * correct / total
|
||||||
print(f'Accuracy on Train Set after Epoch {epoch+1}: {train_accuracy:.2f}%')
|
print(
|
||||||
|
f"Accuracy on Train Set after Epoch {epoch+1}: {train_accuracy:.2f}%")
|
||||||
|
|
||||||
# Calculate accuracy on validation set after each epoch
|
|
||||||
|
def calculate_validation_set_accuracy(training_parameters, epoch):
|
||||||
|
""" Calculate accuracy on validation set after each epoch """
|
||||||
correct = 0
|
correct = 0
|
||||||
total = 0
|
total = 0
|
||||||
for data, targets in test_loader:
|
for data, targets in training_parameters['loaders']['test_loader']:
|
||||||
data = data.view(data.size(0), -1)
|
data = data.view(data.size(0), -1)
|
||||||
outputs = model(data)
|
outputs = training_parameters['model'](data)
|
||||||
_, predicted = torch.max(outputs.data, 1)
|
_, predicted = torch.max(outputs.data, 1)
|
||||||
total += targets.size(0)
|
total += targets.size(0)
|
||||||
correct += (predicted == targets).sum().item()
|
correct += (predicted == targets).sum().item()
|
||||||
|
|
||||||
validation_accuracy = 100 * correct / total
|
validation_accuracy = 100 * correct / total
|
||||||
print(f'Accuracy on Validation Set after Epoch {epoch+1}: {validation_accuracy:.2f}%')
|
print(
|
||||||
print('---')
|
f"Accuracy on Validation Set after Epoch {epoch+1}: {validation_accuracy:.2f}%"
|
||||||
|
)
|
||||||
|
print("---")
|
||||||
|
|
||||||
# Conclusions and observations can be included in the report
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
(
|
||||||
|
HYPERPARAMETERS,
|
||||||
|
TRAIN_LOADER,
|
||||||
|
TEST_LOADER,
|
||||||
|
MODEL,
|
||||||
|
CRITERION,
|
||||||
|
OPTIMIZER,
|
||||||
|
) = initial_configuration()
|
||||||
|
LOADERS = set_loaders(
|
||||||
|
TRAIN_LOADER, TEST_LOADER)
|
||||||
|
TRAINING_PARAMETERS = set_training_parameters(
|
||||||
|
HYPERPARAMETERS, LOADERS, MODEL, CRITERION, OPTIMIZER)
|
||||||
|
training_loop(TRAINING_PARAMETERS)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user