背景
实习生期间被要求做Gan相关的调研,最后要解决一个序列生成的问题,记录一下过程。
介绍
Gan最初的基本思想是存在两个网络,一个生成网络generator,一个判别网络discriminator。 生成网络输入为我们随机的向量,输出为任何我们想要的有意义的东西,比如图片。 判别网络输入为我们需要判别的事物,输出一个数值代表这个事物的质量,也就是真假。 准备好一些真实的数据即可开始训练网络。每次迭代过程,先固定生成网络,将生成网络的输出和真实数据混在一起给判别网络训练,label分别打上0和1;再固定判别网络,回头训练生成网络,使得数据真假无法判别。盗一张学长的图片:
为什么需要两个网络而不能只使用一个生成网络?拿生成图片举例: 如果只用生成网络,常见方法是用编码再解码的方法对图片进行还原,其中解码部分就是生成网络干的事情。实践下来网络的效果不会很好,原因是图片不同像素点其实是独立生成的,它们之间的联系很难被网络考虑进去,这样就需要更复杂的网络结构才能达到一样的效果。使用判别网络可以对生成的图片整个进行判别,将其看作一个整体进行打分,实践下来效果更好。 数学原理 判别器D的目的是在已经有真实样本data和生成样本G(x)的情况下,尽可能对它们进行区分:
D
=
m
a
x
(
E
x
?
d
a
t
a
l
o
g
D
(
x
)
+
E
x
?
G
(
x
)
l
o
g
(
1
?
D
(
x
)
)
)
D=max(E_{x-data}logD(x)+E_{x-G(x)}log(1-D(x)))
D=max(Ex?data?logD(x)+Ex?G(x)?log(1?D(x))) 生成器G的目的是不让判别器区分:
G
=
m
i
n
(
D
)
G=min(D)
G=min(D) 训练过程中首先固定G训练D,(论文)化简得到
D
(
x
)
=
P
r
(
x
)
P
r
(
x
)
+
P
g
(
x
)
D(x)=\frac{Pr(x)}{Pr(x)+Pg(x)}
D(x)=Pr(x)+Pg(x)Pr(x)?其中pr(x)与pg(x)分别代表x处真实样本和生成样本的概率密度,也就是说判别网络D最终在拟合的函数就是这个东西。 将训练好的D代入G,会发现G就是在最小化js散度,最终达到两个分布越来越接近的目的。 理论上来说,训练的最后,生成器生成的样本已经和真实样本没有区别,即Pr(x)=Pg(x),D判别器最终会稳定在1/2。但是实际情况很难达到这种情况,因为Gan的训练十分不稳定,实践下来很难找到一个很好的训练结束的指标。
问题: 1.训练初期,真实样本与生成样本相差过大,js散度可能为0。如果D被训练的过强,G会出现梯度消失。Gan训练十分困难。 2.原作者的改进版使用KL散度,对不能生成正样本的惩罚较大,样本缺少多样性,泛化能力比较差,在实际应用中效果并不突出。
WGan
wgan:改变判别器的作用。判别器本来是一个简单的二分类器,用于判断数据的真实性,现在改成计算wasserstein距离(EM距离),从分类问题变成了回归问题,避免了原来Gan梯度消失的问题。
EM距离解释:现在有两个分布Pr和Pg,如果存在一种移动方案,能把Pr上的所有数据移动到Pg上,则称这种移动方案为r(Pr,Pg),计算出这个方案r中每一个点平均的移动距离,作为衡量这两个分布差异的标准。在所有方案中,选择平均移动距离最少的作为两个分布的EM距离。 wgan使用EM距离代替js散度,由于EM距离无法直接计算,wgan提出一个函数对EM距离进行近似,使用的数学方法为Kantorovich-Rubinstein duality(看不懂)。
问题:最新的文章(2021.3)《Wasserstein GANs Work Because They Fail (to Approximate the Wasserstein Distance)》表明wgan中判别器对于EM距离的拟合其实效果非常差,但是如果使用其他方法对EM距离拟合的更好时,生成器的效果反而下降,所以wgan能成功目前是一个谜。
WGan-GP
wgan-gp:实践发现wgan操作过程中将参数限制在一个小范围中[-0.01,0.01],但是由于wgan的loss希望正负相本差值越大越好,所以权重都集中在[-0.01]和[0.01]上,使得神经网络拟合效果变差。wgan-gp在原来的基础上加入了梯度惩罚,不再对权重进行限制,而是直接将梯度加入loss,让梯度距离某一个特点的k越近越好。实现:
和wgan相比,不需要权重裁剪,只在判别器的loss上加了一个惩罚项:求x处的梯度,并限制在k(k=1)附近。根据lipschitz连续的描述,我们需要在整个样本空间进行采样,这显然不可能,提出者选择采样真实数据和生成数据之间的空间,使用线性插值的方法:,其中random为[0,1]随机数。
LSGan
LSGan:使用最小二乘法损失函数代替原Gan中的交叉熵,同样为了优化Gan训练困难,梯度消失问题。从使用情况来看没有Wgan-gp实用。
DCGan
DCgan(Deep Convolutional):使用卷积层替换全连接层,使用反卷积代替了上采样,每层使用batchnorm,激活函数一般用leakyrelu。最简单确是最有效的改动,方便处理图像。目前大多数简单的项目都可以通过Dcgan实现,比较实用。 自己使用Dcgan尝试的图片生成:
分辨率64*64。
CGan
Cgan(Conditional Gan):加入标签进行训练。真实样本数据不再只有一个1代表真假,而是可以拥有自己的标签,生成器的输入也会相应的加入标签信息来生成对应标签的数据,优点在于可以控制生成器的输出。和传统Gan的区别在于,生成器和判别器的输入通道同时增加,增加类别数量个通道,并将对应类别的通道置1,其余置0。相当于在特定条件下进行训练。
LapGan
LapGan:生成高分辨率图像,使用拉普拉斯金字塔。通过重复堆叠Cgan的方式不断生成分辨率更高的图像。生成器就是在做生成图像的拉普拉斯金字塔的工作。
训练:将训练图片I0下采样,得到I1,将I1上采样得到L0,用I0减去L0得到真实图像,将L0放入生成器中得到生成图像,交给判别器去训练。 从低分辨的图片开始,通过生成器一步一步生成上采样下的残差,通过相加合成高分辨率图像。
PG-Gan
PG-Gan(Progressive Growing):为了生成高分辨率图像,Pg-Gan对整个训练流程做出调整,从4x4的生成图像开始, 直到1024x1024的人脸,渐进式的让生成器和判别器进行增长。效果好于LapGan。
改进: 1.平滑操作,高分辨率的图片由生成器加上低分辨率图片上采样组合而成。
2.放弃使用反卷积,改用上采样+卷积。 3.为了增加样本多样性,为判别器的最后一层添加代表多样性的量度。具体方法为计算feature map上样本之间的标准差。
StyleGan
StyleGan:在Pg-Gan的基础上,加入噪声映射网络,达到控制风格的目的。 1.初始的随机噪声不再直接输入生成器中。因为使用输入向量来控制视觉特征的能力是非常有限的,因为它必须遵循训练数据的概率密度。因此模型无法将部分输入(向量中的元素)映射到特征上,这一现象被称为特征纠缠。然而,通过使用另一个神经网络,该模型可以生成一个不必遵循训练数据分布的向量,并且可以减少特征之间的相关性。
2.在每一个模块随机的加入噪声,来控制一些微小细节的变化,增加样本的随机性。 3.取消batchnorm,转而用adain代替。
效果(图片来自其他博客):
Gan调参技巧: 1.图像生成领域,将真实图像像素值压缩至[-1,1],生成器最后一层使用tanh。 2.训练生成器的时候,把fake样本的label换成real的进行训练。 3.用leakyrelu代替relu,用avgpooling代替maxpooling。 4.真假样本的label不要直接用0和1,可以用0-0.3的随机数和0.7-1.2的随机数。 5.不要将正负样本混合给判别器判别,一个batch全是正样本或负样本是比较好的选择。
文章中大部分公式和图片都来自提出Gan的论文中,真正想了解不同种类Gan的实现方法可以去看论文。下一章讲讲序列生成方面的应用。
|