用于合成新数据的生成对抗网络
1. 简单GAN模型回顾与DCGAN引入
在之前的实验中,生成器网络随着训练的进行生成了越来越逼真的图像。然而,即使经过100个训练周期,生成的图像与MNIST数据集中的手写数字仍有很大差异。之前设计了一个非常简单的GAN模型,生成器和判别器都只有一个全连接隐藏层。在MNIST数据集上训练该GAN模型后,虽然取得了一些有希望的结果,但仍不尽如人意。
在图像分类任务中,带有卷积层的神经网络架构相较于全连接层具有诸多优势。同理,在处理图像数据的GAN模型中添加卷积层可能会改善结果。接下来将实现深度卷积生成对抗网络(DCGAN),其生成器和判别器网络都使用卷积层。
2. 提升合成图像质量的关键技术
为了提升之前GAN示例的性能,将实现DCGAN,并采用以下几种关键技术:
- 转置卷积
- 批量归一化(BatchNorm)
- Wasserstein生成对抗网络(WGAN)
- 梯度惩罚
DCGAN由A. Radford、L. Metz和S. Chintala在2016年提出。从随机向量z开始,DCGAN首先使用全连接层将z投影到一个合适大小的新向量,使其能够重塑为空间卷积表示(h×w×c),该表示小于输出图像的大小。然后,使用一系列称为转置卷积的卷积层将特征图上采样到所需的输出图像大小。
3. 转置卷积
在之前的学习中,了解了一维和二维空间中的卷积操作,特别是填充和步幅的选择如何改变输出特征图。卷积操作通常用于下采样特征空间,而转置卷积操作通常用于上采样特征空间。
为了理解转置卷积操作,进行一个简单的思想实验。假设有一个大小为n×n的输入特征图,对其应用具有特定填充和步幅参数的二维卷积操作,得到大小为m×m的输出特征图。问题是,如何从这个m×m的输出特征图应用另一个卷积操作,以获得具有初始维度n×n的特征图,同时保持输入和输出之间的连接模式。需要注意的是,转置卷积只是恢复特征空间的维度,而不是实际的值。
转置卷积也称为分数步长卷积,在深度学习文献中,另一个常用于指代转置卷积的术语是反卷积。但要注意,反卷积最初被定义为卷积操作的逆操作,而转置卷积仅关注恢复特征空间的维度。
上采样特征图的转置卷积通过在输入特征图的元素之间插入0来实现。以下是一个对大小为4×4的输入应用转置卷积的示例,步幅为2×2,核大小为2×2。中心的9×9矩阵显示了在输入特征图中插入0后的结果。然后,使用2×2的核以步幅1进行正常卷积,得到大小为8×8的输出。可以通过对输出以步幅2进行常规卷积来验证反向过程,结果得到大小为4×4的输出特征图,与原始输入大小相同。
| 操作 | 说明 |
|---|---|
| 输入特征图 | 4×4 |
| 转置卷积(步幅2×2,核2×2) | 插入0后得到9×9矩阵 |
| 正常卷积(步幅1,核2×2) | 输出8×8特征图 |
| 常规卷积(步幅2) | 输出4×4特征图 |
graph LR
A[4×4输入特征图] --> B[转置卷积(步幅2×2,核2×2)]
B --> C[插入0后得到9×9矩阵]
C --> D[正常卷积(步幅1,核2×2)]
D --> E[8×8输出特征图]
E --> F[常规卷积(步幅2)]
F --> G[4×4输出特征图]
4. 批量归一化(BatchNorm)
BatchNorm由Sergey Ioffe和Christian Szegedy在2015年提出,其主要思想是对层输入进行归一化,并防止在训练过程中其分布发生变化,从而实现更快更好的收敛。
BatchNorm基于计算的统计信息对小批量特征进行转换。假设在卷积层之后得到四维张量Z中的净预激活特征图,其形状为[m×h×w×c],其中m是批次中的样本数(即批量大小),h×w是特征图的空间维度,c是通道数。BatchNorm可以总结为以下三个步骤:
1. 计算每个小批量净输入的均值和标准差:
- $\mu_B = \frac{1}{m\times h\times w}\sum_{i,j,k}Z[i,j,k,.]$
- $\sigma_B^2 = \frac{1}{m\times h\times w}\sum_{i,j,k}(Z[i,j,k,.] - \mu_B)^2$
其中,$\mu_B$和$\sigma_B^2$的大小均为c。
2. 对批次中所有样本的净输入进行标准化:
- $Z_{std}[i] = \frac{Z[i] - \mu_B}{\sigma_B + \epsilon}$
其中,$\epsilon$是一个小的数值稳定数,以避免除以零。
3. 使用两个可学习的参数向量$\gamma$和$\beta$(大小为c,即通道数)对标准化后的净输入进行缩放和平移:
- $A_{pre}[i] = \gamma Z_{std}[i] + \beta$
在BatchNorm的第一步中,计算小批量的均值$\mu_B$和标准差$\sigma_B$,它们都是大小为c的向量。然后,在第二步中使用这些统计信息通过z分数归一化(标准化)对每个小批量中的样本进行缩放,得到标准化的净输入$Z_{std}[i]$。这些净输入以均值为中心,具有单位方差,这对于基于梯度下降的优化通常是一个有用的属性。然而,始终将净输入归一化,使其在不同的小批量中具有相同的属性,可能会严重影响神经网络的表示能力。因此,在第三步中,可学习的参数$\beta$和$\gamma$允许BatchNorm控制归一化特征的平移和扩展。
在训练过程中,会计算运行平均值$\mu_B$和运行方差$\sigma_B^2$,并与调整后的参数$\beta$和$\gamma$一起用于在评估时对测试样本进行归一化。
最初,BatchNorm的开发是为了减少所谓的内部协变量偏移,即由于训练过程中网络参数的更新而导致层激活分布发生的变化。但在2018年,有研究表明BatchNorm对内部协变量偏移的影响很小,其有效性可能基于损失函数更平滑的表面,从而使非凸优化更加稳健。
TensorFlow Keras API提供了
tf.keras.layers.BatchNormalization()
类,可在定义模型时作为一个层使用,它将执行上述BatchNorm的所有步骤。需要注意的是,更新可学习参数$\gamma$和$\beta$的行为取决于
training=False
还是
training=True
,这可确保这些参数仅在训练期间学习。
5. 实现生成器和判别器
现在开始实现DCGAN模型的生成器和判别器。
生成器以大小为20的向量z作为输入,应用全连接(密集)层将其大小增加到6272,然后将其重塑为形状为7×7×128的三维张量。接着,使用一系列
tf.keras.layers.Conv2DTransposed()
进行转置卷积,将特征图上采样,直到得到空间维度为28×28的特征图。除最后一层使用单个输出滤波器生成灰度图像外,每个转置卷积层后都跟着BatchNorm和Leaky ReLU激活函数,最后一层使用tanh激活函数(不使用BatchNorm)。
import tensorflow as tf
import numpy as np
def make_dcgan_generator(
z_size=20,
output_size=(28, 28, 1),
n_filters=128,
n_blocks=2):
size_factor = 2**n_blocks
hidden_size = (
output_size[0]//size_factor,
output_size[1]//size_factor)
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(z_size,)),
tf.keras.layers.Dense(
units=n_filters*np.prod(hidden_size),
use_bias=False),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.LeakyReLU(),
tf.keras.layers.Reshape(
(hidden_size[0], hidden_size[1], n_filters)),
tf.keras.layers.Conv2DTranspose(
filters=n_filters, kernel_size=(5, 5),
strides=(1, 1), padding='same', use_bias=False),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.LeakyReLU()
])
nf = n_filters
for i in range(n_blocks):
nf = nf // 2
model.add(
tf.keras.layers.Conv2DTranspose(
filters=nf, kernel_size=(5, 5),
strides=(2, 2), padding='same',
use_bias=False))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.LeakyReLU())
model.add(
tf.keras.layers.Conv2DTranspose(
filters=output_size[2], kernel_size=(5, 5),
strides=(1, 1), padding='same', use_bias=False,
activation='tanh'))
return model
判别器接收大小为28×28×1的图像,图像经过四个卷积层。前三个卷积层在增加特征图通道数的同时将空间维度缩小为原来的四分之一。每个卷积层后都跟着BatchNorm、Leaky ReLU激活函数和丢弃率为0.3的Dropout层。最后一个卷积层使用大小为7×7的核和单个滤波器,将输出的空间维度缩小为1×1×1。
def make_dcgan_discriminator(
input_size=(28, 28, 1),
n_filters=64,
n_blocks=2):
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=input_size),
tf.keras.layers.Conv2D(
filters=n_filters, kernel_size=5,
strides=(1, 1), padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.LeakyReLU()
])
nf = n_filters
for i in range(n_blocks):
nf = nf*2
model.add(
tf.keras.layers.Conv2D(
filters=nf, kernel_size=(5, 5),
strides=(2, 2),padding='same'))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.LeakyReLU())
model.add(tf.keras.layers.Dropout(0.3))
model.add(
tf.keras.layers.Conv2D(
filters=1, kernel_size=(7, 7),
padding='valid'))
model.add(tf.keras.layers.Reshape((1,)))
return model
使用这两个辅助函数,可以构建DCGAN模型并进行训练,使用之前初始化的MNIST数据集对象,也可以使用相同的损失函数和训练过程。不过,需要对
preprocess()
函数进行修改,使其输出图像张量而不是将图像展平为向量。
mnist_bldr = tfds.builder('mnist')
mnist_bldr.download_and_prepare()
mnist = mnist_bldr.as_dataset(shuffle_files=False)
def preprocess(ex, mode='uniform'):
image = ex['image']
image = tf.image.convert_image_dtype(image, tf.float32)
image = image*2 - 1.0
if mode == 'uniform':
input_z = tf.random.uniform(
shape=(z_size,), minval=-1.0, maxval=1.0)
elif mode == 'normal':
input_z = tf.random.normal(shape=(z_size,))
return input_z, image
gen_model = make_dcgan_generator()
gen_model.summary()
disc_model = make_dcgan_discriminator()
disc_model.summary()
在设计卷积GAN时,需要注意生成器和判别器中特征图数量的不同趋势。生成器从大量特征图开始,随着向最后一层推进而减少;判别器则从较少的通道数开始,向最后一层增加。此外,通常不建议在BatchNorm层之后的层中使用偏置单元,因为BatchNorm已经有一个偏移参数$\beta$,使用偏置单元会造成冗余。可以通过在
tf.keras.layers.Dense
或
tf.keras.layers.Conv2D
中设置
use_bias=False
来省略给定层的偏置单元。
需要注意的是,这种特定架构在使用交叉熵作为损失函数时表现不佳。接下来将介绍WGAN,它使用基于真实和虚假图像分布之间的Wasserstein-1(或推土机)距离的修改损失函数来提高训练性能。
用于合成新数据的生成对抗网络
6. 两种分布之间的差异度量
在深入了解WGAN之前,我们需要先探讨不同的方法来计算两个分布之间的差异。然后,我们会分析原始GAN模型中所采用的差异度量方式。最后,通过替换GAN中的差异度量方法,我们将实现WGAN。
生成模型的目标是学习如何合成与训练数据集分布相同的新样本。假设$P(x)$和$Q(x)$分别表示随机变量$x$的分布。以下是几种常见的用于度量两个分布$P$和$Q$之间差异的方法:
| 差异度量方法 | 说明 |
| — | — |
| 总变差(TV)距离 | 测量两个分布在每个点上的最大差异。使用函数上确界$sup(S)$,它指的是大于集合$S$中所有元素的最小值,即$S$的最小上界。 |
| 推土机(EM)距离 | 可以解释为将一个分布转换为另一个分布所需的最小工作量。下确界函数$inf(S)$指的是小于集合$S$中所有元素的最大值,即$S$的最大下界。该距离的下确界是在所有边际分布为$P$或$Q$的联合分布集合$\Pi(P,Q)$上取得的,$\gamma(u, v)$是一个转移计划,它表示如何将“土”从位置$u$重新分配到位置$v$,同时要满足一些约束条件以确保转移后的分布仍然有效。计算EM距离本身就是一个优化问题,即找到最优的转移计划$\gamma(u, v)$。 |
| 库尔贝克 - 莱布勒(KL)散度 | 衡量分布$P$相对于参考分布$Q$的相对熵。需要注意的是,KL散度是非对称的,即$KL(P | Q) \neq KL(Q | P)$。 |
| 詹森 - 香农(JS)散度 | 来自信息论领域,是对称的。 |
这些差异度量方程最初是针对连续分布定义的,但也可以扩展到离散情况。下面通过一个简单的离散分布示例来说明这些度量的计算:
假设我们有两个离散分布$P$和$Q$,对于$x$的不同取值,它们的概率分布如下:
| $x$ | $P(x)$ | $Q(x)$ |
| — | — | — |
| 1 | $1/3$ | $1/6$ |
| 2 | $1/3$ | $1/2$ |
| 3 | $1/3$ | $1/3$ |
对于EM距离,在这个简单示例中,我们可以看到$Q(x)$在$x = 2$处有多余的值$0.5 - 1/3 = 0.166$,而在其他两个$x$值处的值低于$1/3$。因此,最小工作量的转移是将$x = 2$处的多余值转移到$x = 1$和$x = 3$处。
可以从数学上证明,原始GAN中的损失函数实际上是在最小化真实和虚假示例分布之间的JS散度。然而,JS散度在训练GAN模型时存在问题。为了改进训练效果,有研究人员提出使用EM距离作为真实和虚假示例分布之间的差异度量。
下面我们通过一个简单的例子来说明使用EM距离的优势。假设我们有两个分布$P$和$Q$,它们是两条平行线。一条线固定在$x = 0$处,另一条线可以在$x$轴上移动,初始位置为$x = \theta$,其中$\theta > 0$。
可以证明,KL、TV和JS差异度量分别为$KL(P | Q) = +\infty$,$TV(P, Q) = 1$,$JS(P, Q) = \frac{1}{2} \log 2$。这些差异度量都不是参数$\theta$的函数,因此无法针对$\theta$进行求导以推动分布$Q$向分布$P$靠近。而EM距离为$EM(P, Q) = |\theta|$,其关于$\theta$的梯度存在,可以推动$Q$向$P$移动。
graph LR
A[原始GAN损失函数] --> B[最小化JS散度]
B --> C[训练存在问题]
D[改进方法] --> E[使用EM距离]
E --> F[可优化训练]
7. 基于EM距离的WGAN优势
在GAN的训练过程中,选择合适的差异度量对于模型的性能至关重要。传统的GAN使用JS散度作为损失函数的基础,但它存在一些局限性。
当两个分布$P$和$Q$的支持集(即分布非零的区域)不重叠或重叠部分非常小时,JS散度会突然从一个固定值(如$\frac{1}{2} \log 2$)变为$0$,这种不连续性使得在训练过程中梯度消失,导致模型难以学习到有效的特征。
而EM距离具有更好的数学性质。它在分布的支持集不重叠时仍然能够提供有意义的梯度信息,使得模型可以根据这个梯度来调整生成器的参数,从而推动生成的分布向真实分布靠近。
例如,在上述两条平行线的例子中,只要$\theta$不为$0$,EM距离就会随着$\theta$的变化而变化,并且其梯度可以引导模型进行有效的优化。这使得WGAN在训练过程中更加稳定,能够生成更逼真的样本。
8. 总结与展望
通过引入DCGAN和WGAN,我们在生成对抗网络的性能提升方面取得了显著进展。DCGAN通过使用卷积层和转置卷积层,结合BatchNorm技术,能够生成更清晰、更逼真的图像。而WGAN通过采用EM距离作为差异度量,解决了传统GAN在训练过程中可能遇到的梯度消失问题,使得训练更加稳定。
在实际应用中,我们可以根据具体的任务需求选择合适的模型架构和训练方法。例如,如果需要生成高分辨率的图像,可以进一步优化DCGAN的网络结构;如果希望训练过程更加稳定,可以优先考虑使用WGAN。
未来,随着深度学习技术的不断发展,我们可以期待在生成对抗网络领域出现更多的创新和改进。例如,结合更多的正则化技术、探索新的差异度量方法等,以进一步提高生成样本的质量和模型的训练效率。
同时,我们也可以将这些技术应用到更多的领域,如计算机视觉、自然语言处理、医学图像分析等,为这些领域带来新的突破和发展。
以下是一个简单的流程图,总结了我们从简单GAN到DCGAN再到WGAN的发展过程:
graph LR
A[简单GAN] --> B[存在生成图像质量问题]
B --> C[引入DCGAN]
C --> D[使用卷积层和BatchNorm]
D --> E[提升生成图像质量]
E --> F[DCGAN仍有训练问题]
F --> G[引入WGAN]
G --> H[使用EM距离]
H --> I[稳定训练过程]
通过不断地探索和实践,我们相信生成对抗网络将在未来发挥更加重要的作用,为人工智能领域的发展做出更大的贡献。
超级会员免费看
8652

被折叠的 条评论
为什么被折叠?



