class Generator(nn.Module):
def __init__(self, noise_dim=100, img_dim=784):
super(Generator, self).__init__()
self.model = nn.Sequential(
nn.Linear(noise_dim, 256),
nn.LeakyReLU(0.2),
nn.Linear(256, 512),
nn.LeakyReLU(0.2),
nn.Linear(512, 1024),
nn.LeakyReLU(0.2),
nn.Linear(1024, img_dim),
nn.Tanh()
)
def forward(self, noise):
return self.model(noise)
class Discriminator(nn.Module):
def __init__(self, img_dim=784):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.Linear(img_dim, 512),
nn.LeakyReLU(0.2),
nn.Dropout(0.3),
nn.Linear(512, 256),
nn.LeakyReLU(0.2),
nn.Dropout(0.3),
nn.Linear(256, 1),
nn.Sigmoid()
)
def forward(self, img):
return self.model(img)
def train_gan(generator, discriminator, dataloader, num_epochs=100):
criterion = nn.BCELoss()
optimizer_g = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
optimizer_d = optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))
for epoch in range(num_epochs):
for batch_idx, (real_imgs, _) in enumerate(dataloader):
batch_size = real_imgs.size(0)
real_imgs = real_imgs.view(batch_size, -1)
real_labels = torch.ones(batch_size, 1)
fake_labels = torch.zeros(batch_size, 1)
optimizer_d.zero_grad()
real_outputs = discriminator(real_imgs)
real_loss = criterion(real_outputs, real_labels)
noise = torch.randn(batch_size, 100)
fake_imgs = generator(noise)
fake_outputs = discriminator(fake_imgs.detach())
fake_loss = criterion(fake_outputs, fake_labels)
d_loss = real_loss + fake_loss
d_loss.backward()
optimizer_d.step()
optimizer_g.zero_grad()
fake_outputs = discriminator(fake_imgs)
g_loss = criterion(fake_outputs, real_labels)
g_loss.backward()
optimizer_g.step()
print(f"Epoch [{epoch}/{num_epochs}], D_loss: {d_loss.item():.4f}, G_loss: {g_loss.item():.4f}")
class DCGANGenerator(nn.Module):
def __init__(self, noise_dim=100, num_channels=3):
super(DCGANGenerator, self).__init__()
self.main = nn.Sequential(
nn.ConvTranspose2d(noise_dim, 512, 4, 1, 0, bias=False),
nn.BatchNorm2d(512),
nn.ReLU(True),
nn.ConvTranspose2d(512, 256, 4, 2, 1, bias=False),
nn.BatchNorm2d(256),
nn.ReLU(True),
nn.ConvTranspose2d(256, 128, 4, 2, 1, bias=False),
nn.BatchNorm2d(128),
nn.ReLU(True),
nn.ConvTranspose2d(128, 64, 4, 2, 1, bias=False),
nn.BatchNorm2d(64),
nn.ReLU(True),
nn.ConvTranspose2d(64, num_channels, 4, 2, 1, bias=False),
nn.Tanh()
)
def forward(self, noise):
return self.main(noise)