)
在前面的内容中我们已经对生成对抗网络GAN有了一定的理论了解。现在让我们通过一个实际的实战案例以代码演示的方式来看看如何使用GAN完成图像生成任务。通过这个案例你可以更好地掌握GAN在图像生成中的应用同时也能解决图像生成任务中生成图像质量不佳的问题。目录实操步骤数据加载模型训练模型评估总结实操步骤数据加载在进行图像生成任务之前我们首先需要加载合适的图像数据。这里我们以Python中的torchvision库为例它提供了方便的数据加载和预处理功能。importtorchimporttorchvisionimporttorchvision.transformsastransforms# 定义数据预处理transformtransforms.Compose([transforms.Resize((64,64)),# 将图像调整为64x64大小transforms.ToTensor(),# 将图像转换为张量transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))# 归一化处理])# 加载数据集datasettorchvision.datasets.CIFAR10(root./data,trainTrue,downloadTrue,transformtransform)dataloadertorch.utils.data.DataLoader(dataset,batch_size64,shuffleTrue)在这段代码中我们首先定义了数据预处理的步骤包括调整图像大小、转换为张量和归一化处理。然后使用torchvision.datasets.CIFAR10加载CIFAR-10数据集并使用torch.utils.data.DataLoader创建数据加载器方便后续训练时批量加载数据。模型训练接下来我们要定义生成器Generator和判别器Discriminator模型并进行训练。importtorch.nnasnn# 定义生成器classGenerator(nn.Module):def__init__(self):super(Generator,self).__init__()self.mainnn.Sequential(# 输入是一个100维的噪声向量nn.ConvTranspose2d(100,512,4,1,0,biasFalse),nn.BatchNorm2d(512),nn.ReLU(True),# 状态大小: (512) x 4 x 4nn.ConvTranspose2d(512,256,4,2,1,biasFalse),nn.BatchNorm2d(256),nn.ReLU(True),# 状态大小: (256) x 8 x 8nn.ConvTranspose2d(256,128,4,2,1,biasFalse),nn.BatchNorm2d(128),nn.ReLU(True),# 状态大小: (128) x 16 x 16nn.ConvTranspose2d(128,64,4,2,1,biasFalse),nn.BatchNorm2d(64),nn.ReLU(True),# 状态大小: (64) x 32 x 32nn.ConvTranspose2d(64,3,4,2,1,biasFalse),nn.Tanh()# 状态大小: (3) x 64 x 64)defforward(self,input):returnself.main(input)# 定义判别器classDiscriminator(nn.Module):def__init__(self):super(Discriminator,self).__init__()self.mainnn.Sequential(# 输入: (3) x 64 x 64nn.Conv2d(3,64,4,2,1,biasFalse),nn.LeakyReLU(0.2,inplaceTrue),# 状态大小: (64) x 32 x 32nn.Conv2d(64,128,4,2,1,biasFalse),nn.BatchNorm2d(128),nn.LeakyReLU(0.2,inplaceTrue),# 状态大小: (128) x 16 x 16nn.Conv2d(128,256,4,2,1,biasFalse),nn.BatchNorm2d(256),nn.LeakyReLU(0.2,inplaceTrue),# 状态大小: (256) x 8 x 8nn.Conv2d(256,512,4,2,1,biasFalse),nn.BatchNorm2d(512),nn.LeakyReLU(0.2,inplaceTrue),# 状态大小: (512) x 4 x 4nn.Conv2d(512,1,4,1,0,biasFalse),nn.Sigmoid())defforward(self,input):returnself.main(input)# 初始化生成器和判别器generatorGenerator()discriminatorDiscriminator()# 定义损失函数和优化器criterionnn.BCELoss()optimizer_Gtorch.optim.Adam(generator.parameters(),lr0.0002,betas(0.5,0.999))optimizer_Dtorch.optim.Adam(discriminator.parameters(),lr0.0002,betas(0.5,0.999))# 训练循环num_epochs5forepochinrange(num_epochs):fori,datainenumerate(dataloader,0):real_imagesdata[0]batch_sizereal_images.size(0)# 训练判别器discriminator.zero_grad()real_labelstorch.ones(batch_size,1)fake_labelstorch.zeros(batch_size,1)# 计算判别器对真实图像的损失outputdiscriminator(real_images).view(-1)errD_realcriterion(output,real_labels)errD_real.backward()# 生成假图像noisetorch.randn(batch_size,100,1,1)fake_imagesgenerator(noise)# 计算判别器对假图像的损失outputdiscriminator(fake_images.detach()).view(-1)errD_fakecriterion(output,fake_labels)errD_fake.backward()# 更新判别器的参数errDerrD_realerrD_fake optimizer_D.step()# 训练生成器generator.zero_grad()outputdiscriminator(fake_images).view(-1)errGcriterion(output,real_labels)errG.backward()optimizer_G.step()ifi%1000:print(f[{epoch}/{num_epochs}][{i}/{len(dataloader)}] fLoss_D:{errD.item():.4f}Loss_G:{errG.item():.4f})在这段代码中我们首先定义了生成器和判别器的网络结构。生成器的作用是将一个随机噪声向量转换为图像而判别器的作用是判断输入的图像是真实图像还是生成的假图像。然后我们定义了损失函数和优化器使用二元交叉熵损失函数BCELoss来衡量判别器的输出与真实标签之间的差异。在训练过程中我们交替训练判别器和生成器让它们不断对抗从而提高生成图像的质量。模型评估训练完成后我们可以生成一些图像来评估模型的效果。importmatplotlib.pyplotaspltimportnumpyasnp# 生成一些假图像进行评估num_samples16noisetorch.randn(num_samples,100,1,1)generated_imagesgenerator(noise).detach().cpu()# 反归一化处理generated_images(generated_images1)/2.0# 显示生成的图像fig,axesplt.subplots(4,4,figsize(8,8))axesaxes.flatten()foriinrange(num_samples):imggenerated_images[i].permute(1,2,0).numpy()axes[i].imshow(img)axes[i].axis(off)plt.show()在这段代码中我们首先生成一些随机噪声然后使用训练好的生成器生成图像。接着对生成的图像进行反归一化处理最后使用matplotlib库将生成的图像显示出来方便我们直观地评估生成图像的质量。总结通过这个实战案例我们完成了使用GAN进行图像生成的任务包括数据加载、模型训练和评估。你现在已经能够使用GAN完成图像生成任务并且可以通过调整模型结构、训练参数等方法来解决图像生成任务中生成图像质量不佳的问题。掌握了使用GAN完成图像生成任务的内容后下一节我们将深入学习GAN在其他领域的应用进一步完善对本章生成对抗网络主题的认知。