0% found this document useful (0 votes)
2 views9 pages

Experiment No 13 Final

The document contains code for a Generative Adversarial Network (GAN) project using PyTorch, specifically designed to generate images from the MNIST dataset. It includes model definitions for the Discriminator and Generator, hyperparameter settings, dataset loading, and a training loop that logs losses and generates images. Additionally, it provides functionality for visualizing training progress and saving model checkpoints and generated samples.

Uploaded by

atharvzend0
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views9 pages

Experiment No 13 Final

The document contains code for a Generative Adversarial Network (GAN) project using PyTorch, specifically designed to generate images from the MNIST dataset. It includes model definitions for the Discriminator and Generator, hyperparameter settings, dataset loading, and a training loop that logs losses and generates images. Additionally, it provides functionality for visualizing training progress and saving model checkpoints and generated samples.

Uploaded by

atharvzend0
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Experiment No.

13

CODE
# ===============================

# ✅ FINAL GAN PROJECT CODE

# ===============================

# 🔧 SETUP (Remove old logs)

!rm -rf runs

!pip install -q tensorboard

%load_ext tensorboard

%tensorboard --logdir runs

# ===============================

# 🧠 IMPORTS

# ===============================

import torch

import torch.nn as nn

import torch.optim as optim

import torchvision

import torchvision.datasets as datasets

from torch.utils.data import DataLoader

import torchvision.transforms as transforms

from torch.utils.tensorboard import SummaryWriter

import matplotlib.pyplot as plt

import os

# ===============================

# 🧠 MODEL DEFINITIONS

# ===============================

class Discriminator(nn.Module):

def __init__(self, img_dim):

super().__init__()

self.model = nn.Sequential(

nn.Linear(img_dim, 512),
nn.LeakyReLU(0.2),

nn.Linear(512, 256),

nn.LeakyReLU(0.2),

nn.Linear(256, 1),

nn.Sigmoid()

def forward(self, x):

return self.model(x)

class Generator(nn.Module):

def __init__(self, z_dim, img_dim):

super().__init__()

self.model = nn.Sequential(

nn.Linear(z_dim, 256),

nn.BatchNorm1d(256),

nn.LeakyReLU(0.2),

nn.Linear(256, 512),

nn.BatchNorm1d(512),

nn.LeakyReLU(0.2),

nn.Linear(512, img_dim),

nn.Tanh()

def forward(self, x):

return self.model(x)

# ===============================

# ⚙️ HYPERPARAMETERS

# ===============================

device = "cuda" if torch.cuda.is_available() else "cpu"

lr = 1e-4

z_dim = 64

image_dim = 28 * 28

batch_size = 64

num_epochs = 100
# ===============================

# 📦 DATASET & LOADER

# ===============================

transform = transforms.Compose([

transforms.ToTensor(),

transforms.Normalize((0.5,), (0.5,))

])

dataset = datasets.MNIST(root="dataset/", transform=transform, download=True)

loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

# ===============================

# 🧠 INITIALIZE MODELS & OPTIMIZERS

# ===============================

disc = Discriminator(image_dim).to(device)

gen = Generator(z_dim, image_dim).to(device)

opt_disc = optim.Adam(disc.parameters(), lr=lr)

opt_gen = optim.Adam(gen.parameters(), lr=lr)

criterion = nn.BCELoss()

fixed_noise = torch.randn((batch_size, z_dim)).to(device)

writer_fake = SummaryWriter(f"runs/GAN_MNIST/fake")

writer_real = SummaryWriter(f"runs/GAN_MNIST/real")

step = 0

G_losses = []

D_losses = []

# Directory to save generated samples and models

os.makedirs("samples", exist_ok=True)

os.makedirs("models", exist_ok=True)

# ===============================

# 🔁 TRAINING LOOP

# ===============================

for epoch in range(num_epochs):

for batch_idx, (real, _) in enumerate(loader):

real = real.view(-1, image_dim).to(device)

cur_batch_size = real.size(0)
# ========== Train Discriminator ==========

noise = torch.randn(cur_batch_size, z_dim).to(device)

fake = gen(noise)

disc_real = disc(real).view(-1)

lossD_real = criterion(disc_real, torch.ones_like(disc_real) * 0.9) # Label smoothing

disc_fake = disc(fake.detach()).view(-1)

lossD_fake = criterion(disc_fake, torch.zeros_like(disc_fake))

lossD = (lossD_real + lossD_fake) / 2

disc.zero_grad()

lossD.backward()

opt_disc.step()

# ========== Train Generator ==========

output = disc(fake).view(-1)

lossG = criterion(output, torch.ones_like(output)) # Fool the discriminator

gen.zero_grad()

lossG.backward()

opt_gen.step()

# Save losses

G_losses.append(lossG.item())

D_losses.append(lossD.item())

# ========== Logging & Visualization ==========

if batch_idx % 100 == 0:

print(

f"Epoch [{epoch+1}/{num_epochs}] Batch {batch_idx}/{len(loader)} "

f"Loss D: {lossD:.4f}, Loss G: {lossG:.4f}"

with torch.no_grad():

fake = gen(fixed_noise).reshape(-1, 1, 28, 28)

real_imgs = real.reshape(-1, 1, 28, 28)

img_grid_fake = torchvision.utils.make_grid(fake, normalize=True)

img_grid_real = torchvision.utils.make_grid(real_imgs, normalize=True)

writer_fake.add_image("Fake Images", img_grid_fake, global_step=step)

writer_real.add_image("Real Images", img_grid_real, global_step=step)


step += 1

# Save model checkpoints and generated images

if (epoch + 1) % 10 == 0:

torch.save(gen.state_dict(), f"models/generator_epoch_{epoch+1}.pth")

torchvision.utils.save_image(fake, f"samples/fake_epoch_{epoch+1}.png", normalize=True)

# ===============================

# 📊 PLOT LOSS CURVES

# ===============================

plt.figure(figsize=(10, 5))

plt.title("Generator and Discriminator Loss During Training")

plt.plot(G_losses, label="G")

plt.plot(D_losses, label="D")

plt.xlabel("Iterations")

plt.ylabel("Loss")

plt.legend()

plt.savefig("samples/loss_curve.png")

plt.show()

# ===============================

# ✅ FINAL GAN PROJECT CODE

# ===============================

# 🔧 SETUP (Remove old logs)

!rm -rf runs

!pip install -q tensorboard

%load_ext tensorboard

%tensorboard --logdir runs

# ===============================

# 🧠 IMPORTS

# ===============================

import torch

import torch.nn as nn

import torch.optim as optim

import torchvision
import torchvision.datasets as datasets

from torch.utils.data import DataLoader

import torchvision.transforms as transforms

from torch.utils.tensorboard import SummaryWriter

import matplotlib.pyplot as plt

import os

# ===============================

# 🧠 MODEL DEFINITIONS

# ===============================

class Discriminator(nn.Module):

def __init__(self, img_dim):

super().__init__()

self.model = nn.Sequential(

nn.Linear(img_dim, 512),

nn.LeakyReLU(0.2),

nn.Linear(512, 256),

nn.LeakyReLU(0.2),

nn.Linear(256, 1),

nn.Sigmoid()

def forward(self, x):

return self.model(x)

class Generator(nn.Module):

def __init__(self, z_dim, img_dim):

super().__init__()

self.model = nn.Sequential(

nn.Linear(z_dim, 256),

nn.BatchNorm1d(256),

nn.LeakyReLU(0.2),

nn.Linear(256, 512),

nn.BatchNorm1d(512),

nn.LeakyReLU(0.2),

nn.Linear(512, img_dim),
nn.Tanh()

def forward(self, x):

return self.model(x)

# ===============================

# ⚙️ HYPERPARAMETERS

# ===============================

device = "cuda" if torch.cuda.is_available() else "cpu"

lr = 1e-4

z_dim = 64

image_dim = 28 * 28

batch_size = 64

num_epochs = 100

# ===============================

# 📦 DATASET & LOADER

# ===============================

transform = transforms.Compose([

transforms.ToTensor(),

transforms.Normalize((0.5,), (0.5,))

])

dataset = datasets.MNIST(root="dataset/", transform=transform, download=True)

loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

# ===============================

# 🧠 INITIALIZE MODELS & OPTIMIZERS

# ===============================

disc = Discriminator(image_dim).to(device)

gen = Generator(z_dim, image_dim).to(device)

opt_disc = optim.Adam(disc.parameters(), lr=lr)

opt_gen = optim.Adam(gen.parameters(), lr=lr)

criterion = nn.BCELoss()

fixed_noise = torch.randn((batch_size, z_dim)).to(device)

writer_fake = SummaryWriter(f"runs/GAN_MNIST/fake")

writer_real = SummaryWriter(f"runs/GAN_MNIST/real")
step = 0

G_losses = []

D_losses = []

# Directory to save generated samples and models

os.makedirs("samples", exist_ok=True)

os.makedirs("models", exist_ok=True)

# ===============================

# 🔁 TRAINING LOOP

# ===============================

for epoch in range(num_epochs):

for batch_idx, (real, _) in enumerate(loader):

real = real.view(-1, image_dim).to(device)

cur_batch_size = real.size(0)

# ========== Train Discriminator ==========

noise = torch.randn(cur_batch_size, z_dim).to(device)

fake = gen(noise)

disc_real = disc(real).view(-1)

lossD_real = criterion(disc_real, torch.ones_like(disc_real) * 0.9) # Label smoothing

disc_fake = disc(fake.detach()).view(-1)

lossD_fake = criterion(disc_fake, torch.zeros_like(disc_fake))

lossD = (lossD_real + lossD_fake) / 2

disc.zero_grad()

lossD.backward()

opt_disc.step()

# ========== Train Generator ==========

output = disc(fake).view(-1)

lossG = criterion(output, torch.ones_like(output)) # Fool the discriminator

gen.zero_grad()

lossG.backward()

opt_gen.step()

# Save losses

G_losses.append(lossG.item())

D_losses.append(lossD.item())
# ========== Logging & Visualization ==========

if batch_idx % 100 == 0:

print(

f"Epoch [{epoch+1}/{num_epochs}] Batch {batch_idx}/{len(loader)} "

f"Loss D: {lossD:.4f}, Loss G: {lossG:.4f}"

with torch.no_grad():

fake = gen(fixed_noise).reshape(-1, 1, 28, 28)

real_imgs = real.reshape(-1, 1, 28, 28)

img_grid_fake = torchvision.utils.make_grid(fake, normalize=True)

img_grid_real = torchvision.utils.make_grid(real_imgs, normalize=True)

writer_fake.add_image("Fake Images", img_grid_fake, global_step=step)

writer_real.add_image("Real Images", img_grid_real, global_step=step)

step += 1

# Save model checkpoints and generated images

if (epoch + 1) % 10 == 0:

torch.save(gen.state_dict(), f"models/generator_epoch_{epoch+1}.pth")

torchvision.utils.save_image(fake, f"samples/fake_epoch_{epoch+1}.png", normalize=True)

# ===============================

# 📊 PLOT LOSS CURVES

# ===============================

plt.figure(figsize=(10, 5))

plt.title("Generator and Discriminator Loss During Training")

plt.plot(G_losses, label="G")

plt.plot(D_losses, label="D")

plt.xlabel("Iterations")

plt.ylabel("Loss")

plt.legend()

plt.savefig("samples/loss_curve.png")

plt.show()

You might also like