Advertisement

在TensorFlow中使用GAN生成图像

阅读量:

一、说明

本文深入探讨,在tensorflow平台中,在mnist数据集上实现对抗生成网络模型构建。涵盖以下内容:框架搭建阶段(包括神经网络架构设计)、数据预处理流程(涉及图像标准化与批量加载)、生成模型(基于全连接层搭建)、判别模型(基于卷积层设计)、损失函数计算模块(定义交叉熵损失与梯度惩罚)、优化算法配置(采用Adam优化器)等关键环节的具体代码实现。

二、GAN框架介绍

  • 生成器 :此组件负责生成新图像。
  • 鉴别器 :此组件评估生成的图像的质量。

我们构建了一个基于GAN算法生成图像的通用架构如图所示。下面部分简要阐述了如何从数据库中读取数据、设计必要的网络架构、计算损失函数以及进行模型训练的过程。此外还附带了用于验证网络性能并生成新图像代码。

三、读取数据集

MNIST数据集在计算机视觉领域占据重要地位,并包含大量尺寸为28×28像素的手写数字样本。该数据集因其基于灰度且采用单通道图像的独特特点而被视为我们采用GAN进行图像生成的理想数据源。

该代码展示了如何利用Tensorflow内置函数加载MNIST数据集。在成功加载后的内容中接着对图像进行了归一化处理,并将其重塑为三维格式以便于GAN架构下的二维图像处理。此外,在完成模型训练与验证前的步骤中我们还为训练数据和验证数据分配了相应的内存空间。

每个图像的形状被定义为一个28x28x1的矩阵,在此设定中最后一个维度用于表示图像中的通道数量。基于MNIST数据集的特点,在这种情况下我们仅处理单色信息。

在这一具体情境下, 我们将潜在空间的大小(以'zsize'表示)设定为100单位. 该数值可根据具体需求或个人偏好进行相应调整.

复制代码
 from __future__ import print_function, division

    
 from keras.datasets import mnist
    
 from keras.layers import Input, Dense, Reshape, Flatten, Dropout
    
 from keras.layers import BatchNormalization, Activation, ZeroPadding2D
    
 from keras.layers import LeakyReLU
    
 from keras.layers.convolutional import UpSampling2D, Conv2D
    
 from keras.models import Sequential, Model
    
 from keras.optimizers import Adam, SGD
    
 import matplotlib.pyplot as plt
    
 import sys
    
 import numpy as np
    
  
    
 num_rows = 28
    
 num_cols = 28
    
 num_channels = 1
    
 input_shape = (num_rows, num_cols, num_channels)
    
 z_size = 100
    
  
    
 (train_ims, _), (_, _) = mnist.load_data()
    
 train_ims = train_ims / 127.5 - 1.
    
 train_ims = np.expand_dims(train_ims, axis=3)
    
  
    
 valid = np.ones((batch_size, 1))
    
 fake = np.zeros((batch_size, 1))
    
    
    
    
    代码解读

四、定义生成器

生成器(D)在GAN中扮演着至关重要的角色,因为它主要负责生成那些足以欺骗鉴别器的逼真图像。它是GAN系统中构建图像的核心组件之一。在本研究中,我们采用了具有特定架构的生成器设计:该架构包含一个全连接(FC)层,并采用了Leaky ReLU激活函数。值得注意的是,在这一设计中,生成器的最后一层并未采用LeakyReLU激活函数而是采用了TanH激活函数。这种调整的目的在于确保所生成的图像数值范围能够维持在与原始MNIST数据库一致的区间范围(-1, 1)内。

复制代码
 def build_generator():

    
     gen_model = Sequential()
    
     gen_model.add(Dense(256, input_dim=z_size))
    
     gen_model.add(LeakyReLU(alpha=0.2))
    
     gen_model.add(BatchNormalization(momentum=0.8))
    
     gen_model.add(Dense(512))
    
     gen_model.add(LeakyReLU(alpha=0.2))
    
     gen_model.add(BatchNormalization(momentum=0.8))
    
     gen_model.add(Dense(1024))
    
     gen_model.add(LeakyReLU(alpha=0.2))
    
     gen_model.add(BatchNormalization(momentum=0.8))
    
     gen_model.add(Dense(np.prod(input_shape), activation='tanh'))
    
     gen_model.add(Reshape(input_shape))
    
  
    
     gen_noise = Input(shape=(z_size,))
    
     gen_img = gen_model(gen_noise)
    
     return Model(gen_noise, gen_img)
    
    
    
    
    代码解读

五、定义鉴别器

在生成对抗网络(GAN)框架内,鉴别器(D)基于评估机制来区分真实图像与生成图像的核心职责。该组件可被看作一个二元分类任务。为了实现这一目标,在生成对抗网络中通常采用简化的架构配置:全连接层、泄漏ReLU激活以及辍学层等基本组成元素。值得注意的是,在判别器的结构设计中,默认情况下其最后一层会包含一个全连接层,并紧接着应用Sigmoid激活函数以输出所需的分类概率值。

复制代码
 def build_discriminator():

    
     disc_model = Sequential()
    
     disc_model.add(Flatten(input_shape=input_shape))
    
     disc_model.add(Dense(512))
    
     disc_model.add(LeakyReLU(alpha=0.2))
    
     disc_model.add(Dense(256))
    
     disc_model.add(LeakyReLU(alpha=0.2))
    
     disc_model.add(Dense(1, activation='sigmoid'))
    
  
    
     disc_img = Input(shape=input_shape)
    
     validity = disc_model(disc_img)
    
     return Model(disc_img, validity)
    
    
    
    
    代码解读

六、计算损失函数

为了保证生成对抗网络(GAN)中图像生成质量的提升,在选择合适的指标进行性能评估时格外重要。这些参数由损失函数进行定义。

鉴別器負責判斷生成的圖像為真或假並計算相應的概率值。鉴別器旨在通過最大值函數D(x)來區分真實圖片,在展現假造圖片時則使函數D(G(z))達至最小值。

另一方面, 生成器的目标是通过生成看似真实的图像来欺骗判别器. 在数学上, 这一过程涉及对 G(z) 的输出进行缩放. 然而, 仅仅以该组件作为损失函数可能会使网络过于自信地判断错误的结果. 为了应对这一问题, 我们采用损失函数取对数的方法.

GAN生成图像的总体成本函数可以表示为最小游戏:

min_G max_D V(D,G) = E(xp_data(x))(log(D(x))] + E(zp(z))(log(1 – D(G(z)))])

这种GAN训练需要恰当的平衡,并且类似于两方对抗的比赛形式。每个参与者都正致力于利用 minimax 策略去影响并力求超过对方。

我们可以使用二进制交叉熵损失来实现生成器和鉴别器。

对于生成器和鉴别器的实现,我们可以利用二进制交叉熵损失。

复制代码
 # discriminator

    
 disc= build_discriminator()
    
 disc.compile(loss='binary_crossentropy',
    
     optimizer='sgd',
    
     metrics=['accuracy'])
    
  
    
 z = Input(shape=(z_size,))
    
  
    
 # generator
    
 img = generator(z)
    
  
    
 disc.trainable = False
    
  
    
 validity = disc(img)
    
  
    
 # combined model
    
 combined = Model(z, validity)
    
 combined.compile(loss='binary_crossentropy', optimizer='sgd')
    
    
    
    
    代码解读

七、优化损耗

旨在提升网络性能的前提下

考虑到鉴別器与生成器具有不同的损耗特性,在优化过程中难以找到一个统一的标准来衡量两者的性能表现。因此,在实际应用中通常会分别设计并训练每个系统的损失函数。

复制代码
 def intialize_model():

    
     disc= build_discriminator()
    
     disc.compile(loss='binary_crossentropy',
    
     optimizer='sgd',
    
     metrics=['accuracy'])
    
  
    
     generator = build_generator()
    
  
    
     z = Input(shape=(z_size,))
    
     img = generator(z)
    
  
    
     disc.trainable = False
    
  
    
     validity = disc(img)
    
  
    
     combined = Model(z, validity)
    
     combined.compile(loss='binary_crossentropy', optimizer='sgd')
    
     return disc, Generator, and combined
    
    
    
    
    代码解读

在明确设定所有必要特征后, 我们能够构建系统并调节其损失函数. 具体来说, 这包括以下几步: 使用深度神经网络架构搭建生成器和判别器, 并通过交替优化实现图像生成与判别能力的提升.

  • 导入图像并创建一个与导入图像等大的随机音效。
  • 通过比较上传的图片与其生成的声音来判断其真实可能性。
  • 创建一个与前一次相似程度的随机噪声序列,并将其作为生成器的工作输入。
  • 指定时间段长度内进行训练工作。
  • 反复执行上述步骤直至生成效果理想的照片。
复制代码
 def train(epochs, batch_size=128, sample_interval=50):

    
     # load images
    
     (train_ims, _), (_, _) = mnist.load_data()
    
     # preprocess
    
     train_ims = train_ims / 127.5 - 1.
    
     train_ims = np.expand_dims(train_ims, axis=3)
    
  
    
     valid = np.ones((batch_size, 1))
    
     fake = np.zeros((batch_size, 1))
    
     # training loop
    
     for epoch in range(epochs):
    
  
    
     batch_index = np.random.randint(0, train_ims.shape[0], batch_size)
    
     imgs = train_ims[batch_index]
    
     # create noise
    
     noise = np.random.normal(0, 1, (batch_size, z_size))
    
     # predict using a Generator
    
     gen_imgs = gen.predict(noise)
    
     # calculate loss functions
    
     real_disc_loss = disc.train_on_batch(imgs, valid)
    
     fake_disc_loss = disc.train_on_batch(gen_imgs, fake)
    
     disc_loss_total = 0.5 * np.add(real_disc_loss, fake_disc_loss)
    
  
    
     noise = np.random.normal(0, 1, (batch_size, z_size))
    
  
    
     g_loss = full_model.train_on_batch(noise, valid)
    
    
    
     # save outputs every few epochs
    
     if epoch % sample_interval == 0:
    
         one_batch(epoch)
    
    
    
    
    代码解读

八、生成手写数字

基于 MNIST 数据集, 我们为此, 可以开发一个实用程序函数, 以便通过将输入传递给生成器模型来实现预测图像数据. 这个函数会自动生成随机声音作为输入, 并通过执行运算过程来显示并保存生成的图像到特定文件夹中. 为了监控训练进展, 请定期运行此实用程序功能每隔200个周期检查一次. 实现细节如下:

复制代码
 def one_batch(epoch):

    
     r, c = 5, 5
    
     noise_model = np.random.normal(0, 1, (r * c, z_size))
    
     gen_images = gen.predict(noise_model)
    
  
    
     # Rescale images 0 - 1
    
     gen_images = gen_images*(0.5) + 0.5
    
  
    
     fig, axs = plt.subplots(r, c)
    
     cnt = 0
    
     for i in range(r):
    
     for j in range(c):
    
         axs[i,j].imshow(gen_images[cnt, :,:,0], cmap='gray')
    
         axs[i,j].axis('off')
    
         cnt += 1
    
     fig.savefig("images/%d.png" % epoch)
    
     plt.close()
    
    
    
    
    代码解读

在我们的实验中,我们采用了10的批次规模训练了约32个GAN。为了监控训练进展,每隔200个周期我们会定期保存生成图像,并归档至名为"images"的特定目录中。

复制代码
 disc, gen, full_model = intialize_model()

    
 train(epochs=10000, batch_size=32, sample_interval=200)
    
    
    
    
    代码解读

当前阶段对GAN仿真过程中的各个发展节点进行考察:当第Epoch值分别为4百、5千以及1万时。

最初,我们从随机噪声作为生成器的输入开始。

在持续进行了400个epoch的系统性训练后,我们注意到些许进步, 虽然生成的图像与真实数字之间仍存在明显差距

在模型经过长时间(即5, )轮迭代(即经历了总共 N=5, 次)计算过程后,在比较生成样本与真实数据分布的过程中发现了它们之间的显著相似性。

完成完整的 10,000 个 epoch 训练,我们获得以下输出。

这些生成的图像与被用来训练该网络的手写数字样本高度相似。需要注意的是,这些图像并非来自训练数据集本身,并完全是通过神经网络自动生成的。

九、后续步骤

目前,在GAN图像生成领域已经取得了一定成效,并且存在多种方法可以进一步优化性能。在本研究范畴内,则可以考虑尝试引入不同类型的参数以提升效果。以下是一些可能的建议:

  • 研究潜在空间变量不同取值(如z_size)以考察其对系统性能的影响。
  • 扩展训练周期至10,000次以上,并分别延长训练时长至原来的2倍和3倍。
  • 更换现有数据集(如时尚MNIST或移动MNIST)进行测试。这些数据集结构与原MNIST相似,请相应地进行代码修改。
  • 探索替代生成架构(如CycleGAN和DCGAN)。通过调整生成器和判别器设计可深入研究各种模型。

这些更改的实施有助于提升GAN的功能,并为图像生成开辟新的途径。

这些模仿的手written数字样本与网络训练的数据极为接近。
这些图像不属于训练数据集合,并且完全是神经网络创造出来的。

这些模仿的手written数字样本与网络训练的数据极为接近。
这些图像不属于训练数据集合,并且完全是神经网络创造出来的。

十、结论

总体而言而言而言

关键要点

GAN主要包含两个关键模块:一个是生成模块(负责从随机噪声生成新样本),另一个是分辨模块(旨在识别真实与 fake样本)。通过有效的学习过程能够合成一组与手写数字样本高度相似的新样本。为了提升GAN的表现能力,在模型设计中引入了匹配指标和损失函数等优化手段。此外,在不可见数据域上进行评估后,并利用生成器能够产出新的、前所未见的样本。总体而言,在图像合成领域GAN展现出巨大潜力,并广泛应用于机器学习、计算机视觉等多个前沿技术领域。

十一、常见问题

问题 1.什么是生成对抗网络 (GAN)?

回答:生成对抗网络(GAN)其本质是一种基于机器学习的技术框架,在其运行过程中具备生成与训练数据统计特性相似的新数据的能力。该技术不仅限于处理单一类型的数据,在图像、视频以及文本等多种数据类型上均展现出良好的适用性。

问题 2.什么是创意模型?

一种。Generative models belong to the field of machine learning. They are capable of generating new data samples based on input datasets. These models are applied to tasks such as image synthesis, text processing, and various data augmentation scenarios.

问题 3.什么是损失函数?

一个。损失函数是用来衡量两个数据集合之间差异程度的数学工具。在对抗生成网络(GAN)框架内,通过调整构建能够反映生成数据与真实训练数据之间差距的损失函数来训练生成器模型。通常采用带有分类标记并配有点注的图像来进行这一过程。

问题 4.CNN和Gan有什么区别?

答:卷积神经网络(CNN)与生成对抗网络(GAN)均属于深度学习框架,在目标定位上存在显著差异。其中GAN主要用于通过输入噪声样本生成与训练数据相似的新样本的过程设计;而CNN则主要用于图像分类及特征识别等特定任务的解决。值得注意的是尽管将卷积神经网络配置为变分自编码器(VAE)能够使其用于生成任务但在判别性训练方面 CNN表现出色 并且在计算机视觉领域中对图像进行分类的任务处理上更为出色

全部评论 (0)

还没有任何评论哟~