GAN(Generative Adversarial Networks)是一种生成模型,它由两个神经网络组成:生成器和判别器。生成器负责生成假数据,判别器负责区分真假数据。GAN的训练过程是一个博弈过程,生成器和判别器相互竞争,最终生成器可以生成与真实数据相似的假数据。
DCGAN(Deep Convolutional GAN)是GAN的一种改进,它使用卷积神经网络作为生成器和判别器,可以生成更加逼真的图像。
在PyTorch中,我们可以使用MNIST数据集来实现基础GAN和DCGAN。以下是一个完整的攻略,包括两个示例说明。
示例1:基础GAN
首先,我们需要定义生成器和判别器的网络结构。生成器使用全连接层和ReLU激活函数,判别器使用全连接层和Sigmoid激活函数。然后,我们定义损失函数和优化器,并在训练过程中交替训练生成器和判别器。
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
# 定义生成器
class Generator(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(Generator, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.fc2 = nn.Linear(hidden_size, hidden_size)
self.fc3 = nn.Linear(hidden_size, output_size)
self.relu = nn.ReLU()
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
# 定义判别器
class Discriminator(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(Discriminator, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.fc2 = nn.Linear(hidden_size, hidden_size)
self.fc3 = nn.Linear(hidden_size, output_size)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
x = self.sigmoid(self.fc1(x))
x = self.sigmoid(self.fc2(x))
x = self.sigmoid(self.fc3(x))
return x
# 定义超参数
input_size = 784
hidden_size = 256
output_size = 1
num_epochs = 100
batch_size = 64
learning_rate = 0.001
# 加载MNIST数据集
train_dataset = datasets.MNIST(root='data/', train=True, transform=transforms.ToTensor(), download=True)
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
# 创建生成器和判别器实例
generator = Generator(input_size, hidden_size, output_size)
discriminator = Discriminator(input_size, hidden_size, output_size)
# 定义损失函数和优化器
criterion = nn.BCELoss()
g_optimizer = optim.Adam(generator.parameters(), lr=learning_rate)
d_optimizer = optim.Adam(discriminator.parameters(), lr=learning_rate)
# 训练模型
for epoch in range(num_epochs):
for i, (images, _) in enumerate(train_loader):
# 训练判别器
real_labels = torch.ones(batch_size, output_size)
fake_labels = torch.zeros(batch_size, output_size)
real_outputs = discriminator(images.view(batch_size, -1))
d_loss_real = criterion(real_outputs, real_labels)
z = torch.randn(batch_size, input_size)
fake_images = generator(z)
fake_outputs = discriminator(fake_images)
d_loss_fake = criterion(fake_outputs, fake_labels)
d_loss = d_loss_real + d_loss_fake
discriminator.zero_grad()
d_loss.backward()
d_optimizer.step()
# 训练生成器
z = torch.randn(batch_size, input_size)
fake_images = generator(z)
fake_outputs = discriminator(fake_images)
g_loss = criterion(fake_outputs, real_labels)
generator.zero_grad()
g_loss.backward()
g_optimizer.step()
# 打印损失
if (i+1) % 100 == 0:
print(f"Epoch [{epoch}/{num_epochs}], Step [{i+1}/{len(train_loader)}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}")
在这个示例中,我们首先定义了生成器和判别器的网络结构。然后,我们加载MNIST数据集,并定义损失函数和优化器。在训练过程中,我们交替训练生成器和判别器,使用随机噪声生成假数据,并使用真实数据和假数据训练判别器。最后,我们使用损失函数和优化器更新生成器和判别器的参数。
示例2:DCGAN
DCGAN使用卷积神经网络作为生成器和判别器,可以生成更加逼真的图像。我们可以使用PyTorch中的nn.ConvTranspose2d
和nn.Conv2d
函数来定义卷积层和反卷积层。
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
# 定义生成器
class Generator(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(Generator, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.conv1 = nn.ConvTranspose2d(hidden_size, 128, 7, 1, 0)
self.conv2 = nn.ConvTranspose2d(128, 64, 4, 2, 1)
self.conv3 = nn.ConvTranspose2d(64, output_size, 4, 2, 1)
self.relu = nn.ReLU()
self.tanh = nn.Tanh()
def forward(self, x):
x = self.relu(self.fc1(x))
x = x.view(-1, 256, 7, 7)
x = self.relu(self.conv1(x))
x = self.relu(self.conv2(x))
x = self.tanh(self.conv3(x))
return x
# 定义判别器
class Discriminator(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(Discriminator, self).__init__()
self.conv1 = nn.Conv2d(input_size, 64, 4, 2, 1)
self.conv2 = nn.Conv2d(64, 128, 4, 2, 1)
self.conv3 = nn.Conv2d(128, output_size, 7, 1, 0)
self.relu = nn.ReLU()
self.sigmoid = nn.Sigmoid()
def forward(self, x):
x = self.relu(self.conv1(x))
x = self.relu(self.conv2(x))
x = self.sigmoid(self.conv3(x))
return x
# 定义超参数
input_size = 100
hidden_size = 256
output_size = 1
num_epochs = 100
batch_size = 64
learning_rate = 0.0002
# 加载MNIST数据集
train_dataset = datasets.MNIST(root='data/', train=True, transform=transforms.ToTensor(), download=True)
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
# 创建生成器和判别器实例
generator = Generator(input_size, hidden_size, output_size)
discriminator = Discriminator(output_size, hidden_size, output_size)
# 定义损失函数和优化器
criterion = nn.BCELoss()
g_optimizer = optim.Adam(generator.parameters(), lr=learning_rate)
d_optimizer = optim.Adam(discriminator.parameters(), lr=learning_rate)
# 训练模型
for epoch in range(num_epochs):
for i, (images, _) in enumerate(train_loader):
# 训练判别器
real_labels = torch.ones(batch_size, output_size)
fake_labels = torch.zeros(batch_size, output_size)
real_outputs = discriminator(images)
d_loss_real = criterion(real_outputs, real_labels)
z = torch.randn(batch_size, input_size)
fake_images = generator(z)
fake_outputs = discriminator(fake_images.detach())
d_loss_fake = criterion(fake_outputs, fake_labels)
d_loss = d_loss_real + d_loss_fake
discriminator.zero_grad()
d_loss.backward()
d_optimizer.step()
# 训练生成器
z = torch.randn(batch_size, input_size)
fake_images = generator(z)
fake_outputs = discriminator(fake_images)
g_loss = criterion(fake_outputs, real_labels)
generator.zero_grad()
g_loss.backward()
g_optimizer.step()
# 打印损失
if (i+1) % 100 == 0:
print(f"Epoch [{epoch}/{num_epochs}], Step [{i+1}/{len(train_loader)}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}")
在这个示例中,我们首先定义了生成器和判别器的网络结构。生成器使用反卷积层和ReLU激活函数,判别器使用卷积层和Sigmoid激活函数。然后,我们加载MNIST数据集,并定义损失函数和优化器。在训练过程中,我们交替训练生成器和判别器,使用随机噪声生成假数据,并使用真实数据和假数据训练判别器。最后,我们使用损失函数和优化器更新生成器和判别器的参数。
总之,PyTorch提供了丰富的工具和函数来实现GAN和DCGAN。我们可以使用nn.ConvTranspose2d
和nn.Conv2d
函数来定义卷积层和反卷积层,使用nn.BCELoss
函数来定义二元交叉熵损失函数,使用optim.Adam
函数来定义优化器。在训练过程中,我们需要交替训练生成器和判别器,并使用真实数据和假数据训练判别器。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Pytorch使用MNIST数据集实现基础GAN和DCGAN详解 - Python技术站