65.9K
CodeProject 正在变化。 阅读更多。
Home

训练和运行 GAN 以生成时尚设计

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2021年3月22日

CPOL

3分钟阅读

viewsIcon

11370

在本文中,我们将向您展示如何训练 GAN 用于时装设计生成。

引言

DeepFashion 这样的数据集的可用性为时尚产业开辟了新的可能性。 在本系列文章中,我们将展示一个由人工智能驱动的 深度学习 系统,该系统可以通过帮助我们更好地了解客户的需求来彻底改变时装设计行业。

在这个项目中,我们将使用

我们假设您熟悉深度学习的概念,以及 Jupyter Notebook 和 TensorFlow。 如果您不熟悉 Jupyter Notebook,请从 本教程 开始。 欢迎您下载 项目代码

之前的文章 中,我们设计并构建了一个生成对抗网络 (GAN)。 在本文中,我们将训练我们的 GAN 生成逼真的服装图像,类似于 DeepFashion 数据集中找到的图像。

训练 GAN

生成器训练是通过减少假图像和真图像之间的损失和误差 ((log(D(x))+log(D(G(z)) 来完成的。 我们将选择大量的 epoch,因为这种网络需要多次迭代来减少真图像和假图像之间的误差。 我们将从 40 个 epoch 的训练开始,看看会带来什么结果。 我们将在我们定制的数据集上训练网络。 参数和变量定义如下

  • G_losses: 生成器损失,通过对生成器训练期间生成的所有图像的损失求和来计算
  • D_losses: 判别器损失,通过对真实批次和虚假批次的所有损失求和来计算
  • D(G(z): 所有虚假批次的平均判别器输出
  • D(x): 判别器对所有真实批次的平均输出(跨批次)
# Lists to keep track of progress
img_list = []  
G_losses = []  
D_losses = [] 
iters = 0
####################################################################
print("Starting Training Loop...")
# For each epoch
for epoch in range(num_epochs):
    # For each batch in the dataloader
    for i, data in enumerate(dataloader, 0):

        ############################
        # (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
        ###########################
        ## Train with all-real batch
        netD.zero_grad()
        # Format batch
        real_cpu = data[0].to(device)
        b_size = real_cpu.size(0)
        label = torch.full((b_size,), real_label, dtype=torch.float, device=device)
        # Forward pass real batch through D
        output = netD(real_cpu).view(-1)
        # Calculate loss on all-real batch
        errD_real = criterion(output, label)
        # Calculate gradients for D in backward pass
        errD_real.backward()
        D_x = output.mean().item()

        ## Train with all-fake batch
        # Generate batch of latent vectors
        noise = torch.randn(b_size, nz, 1, 1, device=device)
        # Generate fake image batch with G
        fake = netG(noise)
        label.fill_(fake_label)
        # Classify all fake batch with D
        output = netD(fake.detach()).view(-1)
        # Calculate D's loss on the all-fake batch
        errD_fake = criterion(output, label)
        # Calculate the gradients for this batch
        errD_fake.backward()
        D_G_z1 = output.mean().item()
        # Add the gradients from the all-real and all-fake batches
        errD = errD_real + errD_fake
        # Update D
        optimizerD.step()

        ############################
        # (2) Update G network: maximize log(D(G(z)))
        ###########################
        netG.zero_grad()
        label.fill_(real_label)  # fake labels are real for generator cost
        # Since we just updated D, perform another forward pass of all-fake batch through D
        output = netD(fake).view(-1)
        # Calculate G's loss based on this output
        errG = criterion(output, label)
        # Calculate gradients for G
        errG.backward()
        D_G_z2 = output.mean().item()
        # Update G
        optimizerG.step()

        # Output training stats
        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))

        # Save Losses for plotting later
        G_losses.append(errG.item())
        D_losses.append(errD.item())

        # Check how the generator is doing by saving G's output on fixed_noise
        if (iters % 500 == 0) or ((epoch == num_epochs-1) and (i == len(dataloader)-1)):
            with torch.no_grad():
                fake = netG(fixed_noise).detach().cpu()
            img_list.append(vutils.make_grid(fake, padding=2, normalize=True))

        iters += 1

正如您所看到的,在 epoch 40 之后,所有虚假批次的平均判别器输出

D(G(Z)) 降低到一个非常有吸引力的值。 这样,GAN 就有足够的能力来生成与数据集中相似的图像。 如果您想要更好的图像,则需要增加 epoch 的数量并再次训练。

我们还可以绘制一个关于训练期间生成器和判别器损失的图表。

plt.figure(figsize=(10,5))
plt.title("Generator and Discriminator Loss During Training")
plt.plot(G_losses,label="G")
plt.plot(D_losses,label="D")
plt.xlabel("iterations")
plt.ylabel("Loss")
plt.legend()
plt.show()

在训练期间可视化生成的图像

Pytorch 提供了一个用于将训练期间生成的图像可视化为动画视频的函数。

#%%capture
fig = plt.figure(figsize=(8,8))
plt.axis("off")
ims = [[plt.imshow(np.transpose(i,(1,2,0)), animated=True)] for i in img_list]
ani = animation.ArtistAnimation(fig, ims, interval=1000, repeat_delay=1000, blit=True)

HTML(ani.to_jshtml())

从训练好的 GAN 生成时装图像

在我们的 GAN 训练完成后,我们可以使用此代码获取它生成的一批时装图像。

# Grab a batch of real images from the dataloader
real_batch = next(iter(dataloader))

# Plot the real images
plt.figure(figsize=(15,15))
plt.subplot(1,2,1)
plt.axis("off")
plt.title("Real Images")
plt.imshow(np.transpose(vutils.make_grid(real_batch[0].to(device)[:64], padding=5, normalize=True).cpu(),(1,2,0)))

# Plot the fake images from the last epoch
plt.subplot(1,2,2)
plt.axis("off")
plt.title("Fake Images")
plt.imshow(np.transpose(img_list[-1],(1,2,0)))
plt.show()

看起来我们的 GAN 能够生成一些与训练数据集中的图像相似的时装图像。

进一步提高 GAN 性能的一些快速简便的方法是

  • 使用转置卷积或上采样层构建更深层的生成器
  • 将生成器输入噪声的类型更改为高斯
  • 构建一个更深层的判别器以提高其预测性能
  • 使用更多数量的 epoch 和更多图像进行更长时间的训练

后续步骤

我们已经完成了我们的系列! 我们实现了我们的目标:创建一个用于时装设计类别分类的深度网络并对其进行训练,以及使用 GAN 开发一个新的时装设计生成。

尽管如此,我们取得的成果还有待改进。 例如,您可以在包含各种服装类别的更多图像上训练您的深度网络。 您还可以使用 区域提议网络 (RPN) 扩展您的项目,该网络可以在同一图像中检测不同类型的衣服。 这样的网络将使用我们在本系列中创建的预训练模型对服装项目进行分类。

© . All rights reserved.