生成对抗网络应用DCGAN,使用DCGAN完成动漫的生成,并保存每一轮的生成结果图 像。整体代码
时间: 2023-12-29 12:03:45 浏览: 69
很好,这是一个完整的DCGAN生成动漫图像的代码示例。代码基于PyTorch框架实现,同时使用了Google Colab的GPU进行训练加速。
首先,我们需要导入必要的库:
```python
import torch
import torch.nn as nn
from torchvision import datasets, transforms
from torchvision.utils import save_image
import os
```
然后,我们需要定义一些超参数和数据加载器:
```python
# 超参数
latent_size = 100
hidden_size = 64
image_size = 64
num_epochs = 50
batch_size = 128
lr = 0.0002
beta1 = 0.5
ngpu = 1
# 数据集加载器
transform = transforms.Compose([
transforms.Resize(image_size),
transforms.CenterCrop(image_size),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
dataset = datasets.ImageFolder(root='./data', transform=transform)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True, num_workers=2)
```
接下来,我们可以定义生成器和判别器模型:
```python
# 生成器模型
class Generator(nn.Module):
def __init__(self, ngpu):
super(Generator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
# 输入的是一个100维的噪声向量,通过全连接层将其转化为512维向量
nn.Linear(latent_size, hidden_size * 8 * 4 * 4),
nn.BatchNorm1d(hidden_size * 8 * 4 * 4),
nn.ReLU(True),
nn.ConvTranspose2d(hidden_size * 8, hidden_size * 4, 4, 2, 1, bias=False),
nn.BatchNorm2d(hidden_size * 4),
nn.ReLU(True),
nn.ConvTranspose2d(hidden_size * 4, hidden_size * 2, 4, 2, 1, bias=False),
nn.BatchNorm2d(hidden_size * 2),
nn.ReLU(True),
nn.ConvTranspose2d(hidden_size * 2, hidden_size, 4, 2, 1, bias=False),
nn.BatchNorm2d(hidden_size),
nn.ReLU(True),
nn.ConvTranspose2d(hidden_size, 3, 4, 2, 1, bias=False),
nn.Tanh()
)
def forward(self, input):
return self.main(input)
# 判别器模型
class Discriminator(nn.Module):
def __init__(self, ngpu):
super(Discriminator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
nn.Conv2d(3, hidden_size, 4, 2, 1, bias=False),
nn.LeakyReLU(0.2, inplace=True),
nn.Conv2d(hidden_size, hidden_size * 2, 4, 2, 1, bias=False),
nn.BatchNorm2d(hidden_size * 2),
nn.LeakyReLU(0.2, inplace=True),
nn.Conv2d(hidden_size * 2, hidden_size * 4, 4, 2, 1, bias=False),
nn.BatchNorm2d(hidden_size * 4),
nn.LeakyReLU(0.2, inplace=True),
nn.Conv2d(hidden_size * 4, hidden_size * 8, 4, 2, 1, bias=False),
nn.BatchNorm2d(hidden_size * 8),
nn.LeakyReLU(0.2, inplace=True),
nn.Conv2d(hidden_size * 8, 1, 4, 1, 0, bias=False),
nn.Sigmoid()
)
def forward(self, input):
return self.main(input)
```
在实现模型后,我们需要定义优化器和损失函数:
```python
# 定义设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 创建生成器和判别器
netG = Generator(ngpu).to(device)
netD = Discriminator(ngpu).to(device)
# 初始化权重
netG.apply(weights_init)
netD.apply(weights_init)
# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizerD = torch.optim.Adam(netD.parameters(), lr=lr, betas=(beta1, 0.999))
optimizerG = torch.optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))
# 固定噪声向量,用于每轮生成效果的可视化
fixed_noise = torch.randn(64, latent_size, 1, 1, device=device)
```
接下来,我们可以定义训练过程:
```python
# 训练
for epoch in range(num_epochs):
for i, data in enumerate(dataloader, 0):
# 更新判别器
netD.zero_grad()
real_cpu = data[0].to(device)
b_size = real_cpu.size(0)
label = torch.full((b_size,), 1, device=device)
output = netD(real_cpu).view(-1)
errD_real = criterion(output, label)
errD_real.backward()
D_x = output.mean().item()
noise = torch.randn(b_size, latent_size, 1, 1, device=device)
fake = netG(noise)
label.fill_(0)
output = netD(fake.detach()).view(-1)
errD_fake = criterion(output, label)
errD_fake.backward()
D_G_z1 = output.mean().item()
errD = errD_real + errD_fake
optimizerD.step()
# 更新生成器
netG.zero_grad()
label.fill_(1)
output = netD(fake).view(-1)
errG = criterion(output, label)
errG.backward()
D_G_z2 = output.mean().item()
optimizerG.step()
# 输出训练状态
if i % 50 == 0:
print('[%d/%d][%d/%d]\tLoss_D: %.4f\tLoss_G: %.4f\tD(x): %.4f\tD(G(z)): %.4f / %.4f'
% (epoch, num_epochs, i, len(dataloader),
errD.item(), errG.item(), D_x, D_G_z1, D_G_z2))
# 保存生成器模型和可视化生成结果
if (epoch + 1) % 10 == 0:
with torch.no_grad():
fake = netG(fixed_noise).detach().cpu()
img_path = './images/epoch{}.png'.format(epoch+1)
os.makedirs(os.path.dirname(img_path), exist_ok=True)
save_image(fake, img_path, normalize=True)
torch.save(netG.state_dict(), './generator.pth')
```
最后,我们可以生成动漫图像:
```python
# 从保存的生成器模型中加载参数
netG.load_state_dict(torch.load('./generator.pth'))
# 使用训练好的生成器生成新的图像
with torch.no_grad():
noise = torch.randn(1, latent_size, 1, 1, device=device)
fake = netG(noise).detach().cpu()
save_image(fake, './fake_image.png', normalize=True)
```
完整代码如下:
阅读全文