DCGAN图片生成

        DCGAN(Deep Convolutional Generative Adversarial Networks)是一种生成对抗网络,用于生成逼真的图像。它结合了卷积神经网络和生成对抗网络的思想。

        代码如下:

需要导入的相关库:

import os
import random
import numpy as np
import torch
import torch.nn as nn
import torchvision.datasets as dset
import torchvision.transforms as transforms
from torchvision.utils import save_image
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
import torchvision.utils as vutils

 创建文件夹用于保存图片,设置随机数。

os.makedirs("./images/", exist_ok=True)
manualSeed = 111
random.seed = manualSeed
torch.manual_seed(manualSeed)

图片的地址和网络的相关超参数:

dataroot = 'E:/神经网络学习/DCGAN/cartoon_face'
batch_size = 128
image_size = 64
nz = 100
ngf = 64
ndf = 64
lr = 0.0002
betal = 0.5
num_epochs = 100

将图片转成tensor格式,并且使用显卡来进行训练网络。这里还展示了图片内容:

dataset = dset.ImageFolder(root=dataroot,
                           transform=transforms.Compose([
                            transforms.Resize(image_size),
                            transforms.ToTensor(),
                            transforms.Normalize((0.5, 0.5, 0.5),
                                                 (0.5, 0.5, 0.5))
                           ]))

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

device = torch.device('cuda:0' if (torch.cuda.is_available()) else 'cpu')
print('使用的设备是', device)
real_batch = next(iter(dataloader))
plt.figure(figsize=(8, 8))
plt.axis('off')
plt.title('Training image')
plt.imshow(np.transpose(vutils.make_grid(real_batch[0].to(device)[:24],
                        padding=2,
                        normalize=True).cpu(), (1, 2, 0)))
plt.show()

 

接下的代码主要是用于初始化神经网络权重的函数:

def weight_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        nn.init.normal_(m.weight.data, 0.0, 0.02)
    elif classname.find('BatchNorm') != -1:
        nn.init.normal_(m.weight.data, 1.0, 0.02)
        nn.init.constant_(m.bias.data, 0)

 接下来的代码是生成器的代码,这里使用的是反卷积来生成图片的。注意里面的尺寸大小,计算方式如下的公式,这里输入的噪声的尺寸为1×1,经过网络后最终得到的图片尺寸为64×64。

class Generate(nn.Module):
    def __init__(self):
        super(Generate, self).__init__()
        self.main = nn.Sequential(
            nn.ConvTranspose2d(nz, ngf * 8, 4, 1, 0, bias=False),
            nn.BatchNorm2d(ngf * 8),
            nn.ReLU(True),
            nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf*4),
            nn.ReLU(True),
            nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 2),
            nn.ReLU(True),
            nn.ConvTranspose2d(ngf * 2, ngf, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf),
            nn.ReLU(True),
            nn.ConvTranspose2d(ngf, 3, 4, 2, 1, bias=False),
            nn.Tanh()
        )

    def forward(self, input):
        return self.main(input)


net_G = Generate().to(device)
net_G.apply(weight_init)
print(net_G)

接下来就是判别器的代码,判别器的代码比较简单,类似于普通卷积神经网络在做分类任务,只不过这里就是一个简单的二分类任务。

class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()

        self.main = nn.Sequential(
            nn.Conv2d(3, ndf, 4, 2, 1, bias=False),
            nn.LeakyReLU(0.2, True),
            nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 2),
            nn.LeakyReLU(0.2, True),
            nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 4),
            nn.LeakyReLU(0.2, True),
            nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 8),
            nn.LeakyReLU(0.2, True),
            nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False),
            nn.Sigmoid()
        )

    def forward(self, input):
        return self.main(input)


net_D = Discriminator().to(device)
net_D.apply(weight_init)
print(net_D)

接下来就是设置了GAN训练所需的损失函数、固定的噪声输入、真实与生成样本的标签,以及用于优化判别器和生成器的Adam优化器。这些步骤是GAN训练中常见的初始化和设置步骤,用于确保模型在训练过程中能够正确地更新参数和计算损失。

criterion = nn.BCELoss().to(device)
fix_noise = torch.randn(64, nz, 1, 1, device=device)

real_label = 1
fake_label = 0

optimizerD = torch.optim.Adam(net_D.parameters(), lr=lr, betas=(betal, 0.999))
optimizerG = torch.optim.Adam(net_G.parameters(), lr=lr, betas=(betal, 0.999))

 下面这段代码就是训练了:

for epoch in range(num_epochs):
    for i, data in enumerate(dataloader, 0):
        net_D.zero_grad()
        real_cpu = data[0].to(device)
        b_size = real_cpu.size(0)
        label = torch.full((b_size,), real_label, dtype=torch.float, device=device)
        output = net_D(real_cpu).view(-1)
        errD_real = criterion(output, label)
        errD_real.backward()
        D_x = output.mean().item()
        optimizerD.step()

        noise = torch.randn(b_size, nz, 1, 1, device=device)
        fake = net_G(noise)
        label.fill_(fake_label)
        output = net_D(fake.detach()).view(-1)
        errD_fake = criterion(output, label)
        errD_fake.backward()
        D_G_z1 = output.mean().item()
        errD = errD_fake + errD_real
        optimizerD.step()

        net_G.zero_grad()
        label.fill_(real_label)
        output = net_D(fake).view(-1)
        errG = criterion(output, label)
        errG.backward()

        D_G_z2 = output.mean().item()
        optimizerG.step()

        if i % 400 == 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))

        G_loss.append(errG.item())
        D_loss.append(errD.item())

        if (iters % 500 == 0) or ((epoch == num_epochs - 1) and (i == len(dataloader) - 1)):
            with torch.no_grad():
                fake = net_G(fix_noise).detach().cpu()
            save_image(fake, './images/%d.png' % iters)

        iters += 1

这里列举训练结果:

 

这里这要问题是生成器的功能还不够强大,以至于生成的图片不能满足要求,接下来就需要对生成器网络进行改进。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值