失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【机器学习】生成对抗网络(GAN)

【机器学习】生成对抗网络(GAN)

时间:2022-03-31 09:21:41

相关推荐

【机器学习】生成对抗网络(GAN)

本文为机器学习的学习总结,讲解生成对抗网络(GAN)。欢迎在评论区与我交流 😃

导论

GAN 的基本概念

在 GAN 中,我们需要训练一个生成器(Generator),输入一个向量,让机器生成一些影像或诗词:

条件生成器输入已知的东西,而不是随机的向量,例如输入文字,让机器输出对的图片。条件生成器有很多应用,之后会详细讲解。

生成器是一个神经网络,即一个函数。在影像生成中,输出的图片就是高维向量。例如输入向量,输出头像,向量每一维代表一个特征:

与此同时,我们还会训练识别器(discriminator),识别器也是一个神经网络。例如输入图片,输出代表真实度的数值。

例如下面的例子,枯叶蝶是生成器,麻雀是识别器。枯叶蝶为了避免被捕食会不断进化,而麻雀为了捕食猎物也会不断进化:

识别器判断图片生成器生成的还是真实的图片,此时标准可能是是否为彩色等简单的标准。下一代的生成器想办法骗过第一代的识别器,从而进化到第二代;然后识别器也进化到第二代,学会判断第二代生成器与真实图片的差异。如此往复,不断进化。像天敌和被捕食者的关系。

当然对抗关系只是一种比喻,从另一个角度看也可以是互助的关系。例如学生画画(生成器),老师告诉学生如何画(识别器)。老师的标准不断严格,学生的水平也不断提高。

那么生成器为什么不自己学?识别器为什么不自己做?这两个问题我们后面会讲到。

这里用语言描述算法步骤:

首先随机初始化生成器和识别器。

在每次迭代中:

固定生成器 GGG,更新识别器参数。数据库给出范例,训练目标是:数据库范例输入时,输出 1;生成器图像输入时,输出 0.固定识别器 DDD,调整生成器参数。生成器需要骗过识别器,希望生成器输出的图像,识别器能给高分,从而使生成的图像更真实。

实际中将生成器和识别器的神经网络和起来形成一个更大的神经网络,其中中间某层(隐藏层)输出一个图像。调参时固定一部分层的参数,调另一部分。

然后我们对算法进行数学描述:

初始化 DDD 的参数 θd\theta_dθd​ 和 GGG 的参数 θg\theta_gθg​。

在每次迭代中:

更新识别器参数 θd\theta_dθd​

在数据库中选取 mmm 个样本 {x1,…,xm}\{x^1,…,x^m\}{x1,…,xm}

从随机分布中选取 mmm 个样本 {z1,…,zm}\{z^1,…,z^m\}{z1,…,zm}

计算生成器结果(产生图片) {x~1,…,x~m}\{\tilde{x}^1,…,\tilde{x}^m\}{x~1,…,x~m},其中 x~i=G(zi)\tilde{x}^i=G(z^i)x~i=G(zi)

最大化 V~\tilde{V}V~ 从而更新识别器参数 θd\theta_dθd​,因为值在 0-1 之间,不用使用 sigmod 函数。

V~=1m∑i=1mlog⁡D(xi)+1m∑i=1mlog⁡(1−D(x~i))\tilde{V}=\frac{1}{m}\sum\limits_{i=1}^m\log{D(x^i)}+\frac{1}{m}\sum\limits_{i=1}^m\log(1-D(\tilde{x}^i)) V~=m1​i=1∑m​logD(xi)+m1​i=1∑m​log(1−D(x~i))

梯度下降法更新公式。这里因为是最大化 V~\tilde{V}V~,因此这里为加号。

θd←θd+η∇V~(θd)\theta_d\leftarrow\theta_d+\eta\nabla\tilde{V}(\theta_d) θd​←θd​+η∇V~(θd​)

更新生成器参数 θg\theta_gθg​

从随机分布中选取 mmm 个样本 {z1,…,zm}\{z^1,…,z^m\}{z1,…,zm}

最大化 V~\tilde{V}V~ 从而更新生成器参数 θg\theta_gθg​:

V~=1m∑i=1mlog⁡(D(G(zi)))\tilde{V}=\frac{1}{m}\sum\limits_{i=1}^m\log(D(G(z^i))) V~=m1​i=1∑m​log(D(G(zi)))

梯度下降法更新公式:

θg←θg+η∇V~(θg)\theta_g\leftarrow\theta_g+\eta\nabla\tilde{V}(\theta_g) θg​←θg​+η∇V~(θg​)

GAN 作为结构化学习

首先简单介绍一下结构化学习(structured learning)。在回归和分类问题中,我们输出的结果为值和类型。如果我们需要输出的预测为序列、矩阵、图或树等,这就称为结构化学习。例如机器翻译、演讲识别和聊天机器人都输出一个句子。

为什么结构化学习具有挑战性

如果将结构化学习中每个句子都看作是一个类别,在预测时输出的句子很可能在训练时从没见过,我们将其视为创造。因此,结构化学习可以看作是一个极端的单/零样本学习(one-shot/zero-shot learning)。单/零样本学习是指我们之前没有这个类别的训练样本,或训练样本极少。

结构化学习中,机器生成的对象是有很多部分组成的,这些部分相互依赖,组成的整体才是有意义的,因此机器需要有整体的概念,而不是每次只关注生成一个像素值。例如输出图像的例子,机器首先在图像中间输出一个黑点,我们无法判断此时这个是正确还是错误的,只有完全输出图像时,我们才能知道黑点的正确性:

结构化学习中有 2 类方法:

Botton Up:从每个部件开始生成对象,即生成器的方法。缺点是无法了解到整体的正确性。Top Down:估计每个对象整体,从而找到最好的一个,即识别器的方法。缺点是很难进行生成,后面会详细讲。

生成器自主学习

在传统监督学习中,提供给机器训练集,不断训练就能得到结果。而现在我们需要输入向量,输出图像,生成器的传统监督学习方法与手写数字识别相反。

如果生成器自主学习,训练集需要给出每个图像对应的一个向量。但是这个向量很难选择,如果随机赋值,那么相似度较高的图像对应的向量距离可能会很大,我们不希望这种情况发生。

对于向量如何赋值的问题,我们可以训练编码神经网络(NN Encoder),输入一张图片,输出一个向量:

使用自编码器来训练编码神经网络。同时编码和解码神经网络,将编码神经网络输出的向量作为解码神经网络的输出,从而解码神经网络输出一个图像,我们要使得输入图像和输出图像越像越好。

我们很容易发现,此时的 Decoder 神经网络就是我们要求的生成器。例如一个数字生成器,输入一个二维向量,输出一张图形:

横轴表示是否有圈,纵轴表示方向。

自编码器还有一个问题,如果我们输入向量 a,输出向左的 1,输入向量 b,输出向右的 1。如果输入 a 和 b 的平均向量,我们希望会产生竖直的 1,但因为神经网络是非线性的,产生的结果可能为噪声。

我们需要用 VAE(Variational Auto-encoder)解决这个问题。这里编码器不仅输出向量编码,还输出 σi\sigma_iσi​(越接近 1 越好),从正态分布中选几个样本与 σi\sigma_iσi​ 相乘,加到向量编码 mim_imi​ 上,解码器再根据有噪声的向量还原图片:

这样解码器训练地会更加稳定。

通常向量是低维度的,图像是高维度的,但其分布本质为低维度的。向量的维度需要进行调整。单纯提高向量的维度可能并没用,虽然代价会更低,但性能可能并不会很好。

训练生成器造成丢失

生成器生成的图像要越像真实图片越好,在训练生成器时,我们将两张图片写成向量,计算每个像素间的距离,然后最小化这个距离。

但是在实际训练的时候,生成器会出错误,在某些地方不得不做妥协,误差位置也很重要,例如下图中第一行虽然只有 1 个像素的误差,但图像却无法正确识别;第二行虽然相差 6 个像素,但误差位置比较好,只是笔画长了一些,相似度还是很高的。因此我们不能单纯的计算图像间的距离。

假定我们已经知道了 L-1 层神经元的值,现在要求最后一层神经元的值,我们期望的是最后一层神经元的部分之间的像素值之间不要差太多,这样才不会出现下图中最左边图中离群的点,但最后一层的输出并不会考虑这个问题。

这就是单独学习一个生成器困难的地方。

但其实这种情况也是有解的,我们可以多加几层隐藏层就可以将像素的相关性考虑进来。因此,对于同样一个任务,用自编码器单纯训练生成器的神经网络的深度要远远大于用 GAN 训练。

用生成器得到的最好结果为蓝色点所示,绿色点为目标结果。可以看出在每个分布之间还有一些蓝色的点,效果并不好。

为什么识别器无法生成

识别器

输入一个对象,输出这个对象有多好(scalar)。识别器产生对象时比生成器更容易考虑到部件间的关系,因为识别器的输入是生成好的完整图片。例如识别子是卷积神经网络,其中一个过滤器如下,该过滤器判断是否有孤立像素,如果有就给低分。

假设我们已经有识别器,穷举所有可能的 xxx 作为输入,得到最高分的 xxx 就是生成结果:

x~=arg⁡max⁡x∈XD(x)\tilde{x}=\arg\max\limits_{x\in X} D(x) x~=argx∈Xmax​D(x)

识别器需要输入正样本(输出为 1)和负样本(输出为 0)进行训练,而此时训练集中只有正样本。我们还需要一些负样本,如果负样本只是白噪声,那么识别器可能会将除了白噪声以外的图像都视为真实图像,因此负样本的质量需要很高。产生质量好的负样本则需要一个好的识别器,而一个好的识别器又需要质量好的负样本,如此便陷入了死循环中。

识别器的训练算法:

输入正样本集和随机生成的负样本集

每次迭代中:

训练识别器,使其能区别出正负样本解 x~=arg⁡max⁡x∈XD(x)\tilde{x}=\arg\max\limits_{x\in X} D(x)x~=argx∈Xmax​D(x) 问题,用识别器生成样本。在下一代迭代中,将随机生成的负样本换成识别器生成的样本

在实际中,特征维度会很多,我们很难像下图一维空间中将除了正样本以外的所有 D(x)D(x)D(x) 都压低:

算法的做法是,对于下面的样本点,绿色代表真实图像,蓝色代表生成的图像,在一次学习后可能得到的识别器函数为 D(x)D(x)D(x),在没有样本的地方识别器的值可能会高于真实图像:

识别器会给自己生成的图片高分:

在下一次迭代中,识别器学习到要给自己产生的图像低分,将右侧的图像压低:

算法寻找识别器的弱点,找到非正样本的高分部分,将其压低。

最终正负样本的分布重合,算法收敛:

于是,仅用识别器也可以做生成。

生成器 VS 识别器

因此我们将生成器和识别器结合,将识别器中很难计算的 arg⁡max⁡\arg\maxargmax 问题用生成器解决,生成器可以很容易地生成高分样本。这种做法十分有效且容易一般化。生成器仍然一部分一部分地产生对象,但得到的代价反馈不再是像素间的距离,而是一个有全局观的识别器。

GAN 产生的结果见下图,簇之间几乎没有杂点:

我们来比较一下 GAN 和 VAE 的性能。下图纵轴越小说明产生图片越相似,GAN 通常很敏感,只有特定参数才能训练,因此其性能有很大的范围。左边为生成数字的数据集,右边为生成 10 种不同图案的数据集。

赋予不同的参数,VAE 的性能比较稳定,但其最佳性能与 GAN 有很大的差距。

有帮助的话点个赞加关注吧 😃

如果觉得《【机器学习】生成对抗网络(GAN)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。