Skip to content

Instantly share code, notes, and snippets.

@ecsplendid
Last active May 19, 2024 09:10
Show Gist options
  • Save ecsplendid/10afbff2f878fe31fd44e1404e98a1b7 to your computer and use it in GitHub Desktop.
Save ecsplendid/10afbff2f878fe31fd44e1404e98a1b7 to your computer and use it in GitHub Desktop.
// note: gpt4-o generated, probably buggy
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, random_split, TensorDataset
import numpy as np
import matplotlib.pyplot as plt
# Load MNIST data
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
# Split the dataset into training and validation sets
train_size = int(0.8 * len(train_dataset))
val_size = len(train_dataset) - train_size
train_dataset, val_dataset = random_split(train_dataset, [train_size, val_size])
# Preprocess data
train_images = train_dataset.dataset.data[train_dataset.indices].view(-1, 28*28).float() / 255.0
train_labels = train_dataset.dataset.targets[train_dataset.indices]
# Randomize half of the labels to be wrong in the training set
random_train_labels = train_labels.clone()
num_labels = len(train_labels)
num_randomize = num_labels // 2
indices = np.random.choice(num_labels, num_randomize, replace=False)
for i in indices:
possible_labels = list(range(10))
possible_labels.remove(train_labels[i].item())
random_train_labels[i] = np.random.choice(possible_labels)
# Create a dataset with shuffled labels
shuffled_train_dataset = TensorDataset(train_images, random_train_labels)
# Create data loaders
batch_size = 128
train_loader = DataLoader(shuffled_train_dataset, batch_size=batch_size, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
# Define the model
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(28*28, 512)
self.fc2 = nn.Linear(512, 10)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
device = torch.device("mps" if torch.backends.mps.is_available() else "cuda" if torch.cuda.is_available() else "cpu")
model = SimpleNN().to(device)
# Define loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.RMSprop(model.parameters(), lr=0.001)
# Train the model
num_epochs = 100
train_losses = []
val_losses = []
for epoch in range(num_epochs):
model.train()
train_loss = 0
for images, labels in train_loader:
images = images.to(device)
labels = labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
train_loss += loss.item()
train_loss /= len(train_loader)
train_losses.append(train_loss)
model.eval()
val_loss = 0
with torch.no_grad():
for images, labels in val_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
loss = criterion(outputs, labels)
val_loss += loss.item()
val_loss /= len(val_loader)
val_losses.append(val_loss)
print(f"Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss:.4f}, Validation Loss: {val_loss:.4f}")
# Plot the training and validation loss
plt.plot(train_losses, label='Training loss')
plt.plot(val_losses, label='Validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.title('Training and Validation Loss on MNIST with Random Labels')
plt.savefig("mnist_plot_half_random.jpg")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment