Files
2024-12-11 13:29:29 +08:00

155 lines
4.4 KiB
Python

import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
# Super parameters
batch_size = 64
learning_rate = 0.01
momentum = 0.5
EPOCH = 10
# Prepare dataset
transform = transforms.Compose(
[transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]
)
train_dataset = datasets.MNIST(
root="./data/mnist", train=True, download=True, transform=transform
)
test_dataset = datasets.MNIST(
root="./data/mnist", train=False, download=True, transform=transform
)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
class Net3Layer(torch.nn.Module):
def __init__(self):
super(Net3Layer, self).__init__()
self.fc1 = torch.nn.Linear(28 * 28, 512)
self.fc2 = torch.nn.Linear(512, 128)
self.fc3 = torch.nn.Linear(128, 10)
def forward(self, x):
x = x.view(-1, 28 * 28)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
class Net9Layer(torch.nn.Module):
def __init__(self):
super(Net9Layer, self).__init__()
self.fc1 = torch.nn.Linear(28 * 28, 512)
self.fc2 = torch.nn.Linear(512, 512)
self.fc3 = torch.nn.Linear(512, 256)
self.fc4 = torch.nn.Linear(256, 256)
self.fc5 = torch.nn.Linear(256, 128)
self.fc6 = torch.nn.Linear(128, 128)
self.fc7 = torch.nn.Linear(128, 64)
self.fc8 = torch.nn.Linear(64, 64)
self.fc9 = torch.nn.Linear(64, 10)
def forward(self, x):
x = x.view(-1, 28 * 28)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = F.relu(self.fc3(x))
x = F.relu(self.fc4(x))
x = F.relu(self.fc5(x))
x = F.relu(self.fc6(x))
x = F.relu(self.fc7(x))
x = F.relu(self.fc8(x))
x = self.fc9(x)
return x
# Create two models
model_3layer = Net3Layer()
model_9layer = Net9Layer()
# Create optimizers
optimizer_3layer = torch.optim.SGD(
model_3layer.parameters(), lr=learning_rate, momentum=momentum
)
optimizer_9layer = torch.optim.SGD(
model_9layer.parameters(), lr=learning_rate, momentum=momentum
)
criterion = torch.nn.CrossEntropyLoss()
def train(epoch, model, optimizer, name=""):
model.train()
running_loss = 0.0
running_total = 0
running_correct = 0
for batch_idx, (inputs, target) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
running_loss += loss.item()
_, predicted = torch.max(outputs.data, dim=1)
running_total += target.shape[0]
running_correct += (predicted == target).sum().item()
avg_loss = running_loss / len(train_loader)
avg_acc = 100 * running_correct / running_total
print(
f"[{epoch + 1} / {EPOCH}]: {name} Training Loss: {avg_loss:.3f}, Training Accuracy: {avg_acc:.2f} %"
)
def test(epoch, model, name=""):
model.eval()
correct = 0
total = 0
with torch.no_grad():
for data in test_loader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs.data, dim=1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
acc = 100 * correct / total
print(
f"[{epoch + 1} / {EPOCH}]: {name} Accuracy on test set after epoch {epoch + 1}: {acc:.1f} %"
)
return acc
if __name__ == "__main__":
acc_list_3layer = []
acc_list_9layer = []
for epoch in range(EPOCH):
train(epoch, model_3layer, optimizer_3layer, "3-Layer")
train(epoch, model_9layer, optimizer_9layer, "9-Layer")
acc_3layer = test(epoch, model_3layer, "3-Layer")
acc_9layer = test(epoch, model_9layer, "9-Layer")
acc_list_3layer.append(acc_3layer)
acc_list_9layer.append(acc_9layer)
plt.figure(figsize=(10, 6))
plt.plot(range(1, EPOCH + 1), acc_list_3layer, label="3-Layer Network", marker="o")
plt.plot(range(1, EPOCH + 1), acc_list_9layer, label="9-Layer Network", marker="s")
plt.xlabel("Epoch")
plt.ylabel("Accuracy On TestSet (%)")
plt.title("Comparison of Network Depths")
plt.legend()
plt.grid(True)
plt.show()