guiBackend / GAN /GAN_Architecture.py
BrianLov's picture
Upload folder using huggingface_hub
068b6e0 verified
Raw
History Blame Contribute Delete
3.97 kB
import torch
import torch.nn as nn
class Generator(nn.Module):
def __init__(self, latent_dim=100):
super(Generator, self).__init__()
# Mapping the 100-dimension noise vector to a 7x7 spatial foundation
self.init_size = 7
self.l1 = nn.Sequential(nn.Linear(latent_dim, 256 * self.init_size ** 2))
# Using kernel=4, stride=2, padding=1 perfectly doubles the resolution at each step
self.conv_blocks = nn.Sequential(
nn.BatchNorm2d(256),
# 7x7 -> 14x14
nn.ConvTranspose2d(256, 128, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(128),
nn.LeakyReLU(0.2, inplace=True),
# 14x14 -> 28x28
nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(64),
nn.LeakyReLU(0.2, inplace=True),
# 28x28 -> 56x56
nn.ConvTranspose2d(64, 32, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(32),
nn.LeakyReLU(0.2, inplace=True),
# 56x56 -> 112x112
nn.ConvTranspose2d(32, 16, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(16),
nn.LeakyReLU(0.2, inplace=True),
# 112x112 -> 224x224
# Output is 1 channel (Grayscale) and uses Tanh to map pixels to [-1, 1]
nn.ConvTranspose2d(16, 1, kernel_size=4, stride=2, padding=1),
nn.Tanh()
)
def forward(self, z):
out = self.l1(z)
out = out.view(out.shape[0], 256, self.init_size, self.init_size)
img = self.conv_blocks(out)
return img
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
def discriminator_block(in_filters, out_filters, bn=True):
block = [
# Wrap the convolution in spectral normalization
nn.utils.spectral_norm(nn.Conv2d(in_filters, out_filters, kernel_size=4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.Dropout2d(0.25)
]
if bn:
block.append(nn.BatchNorm2d(out_filters, 0.8))
return block
self.model = nn.Sequential(
# Input: 1 x 224 x 224
*discriminator_block(1, 16, bn=False), # 112x112
*discriminator_block(16, 32), # 56x56
*discriminator_block(32, 64), # 28x28
*discriminator_block(64, 128), # 14x14
*discriminator_block(128, 256), # 7x7
)
# The downsampled image is flattened and fed into a single neuron to guess: Real or Fake?
ds_size = 7
self.adv_layer = nn.Sequential(
nn.Linear(256 * ds_size ** 2, 1),
nn.Sigmoid()
)
def forward(self, img):
out = self.model(img)
out = out.view(out.shape[0], -1)
validity = self.adv_layer(out)
return validity
if __name__ == "__main__":
print("Testing GAN Dimensions...")
# 1. Create a dummy noise vector (Batch Size of 2, 100 random numbers each)
latent_dim = 100
z = torch.randn(2, latent_dim)
# 2. Test Generator
gen = Generator(latent_dim)
fake_imgs = gen(z)
print(f"Generator Output Shape: {fake_imgs.shape}")
# EXPECTED: [2, 1, 224, 224] (2 images, 1 channel, 224x224 pixels)
# 3. Test Discriminator
disc = Discriminator()
validity = disc(fake_imgs)
print(f"Discriminator Output Shape: {validity.shape}")
# EXPECTED: [2, 1] (2 guesses between 0.0 and 1.0)
print("If you see [2, 1, 224, 224] and [2, 1], the architecture is perfectly locked in!")