写在前面的说明
这个系列【ML-2020/21】大部分是课上内容的简单复述,之前上过但因为笔记写得很乱就忘了很多,所以重来一遍。与其看我这篇,不如直接去看视频,讲得还更生动。视频系列链接 → \rightarrow →这里。
基本概念
Generative Adversarial Network (GAN) 中文名是【生成式对抗网络】,用这个网络的目的是为了让机器生成东西(比如图片,文章等),其基本网络结构包括两大部分:
- Generation:生成器
- Discriminator:鉴别器
Generation
在generation过程中我们需要做的就是训练一个生成器,比如在影像生成中,我们希望得到一个生成器,随便输入一个向量,通过这个生成器能得到一张对应图片,不同的向量对应不同的图片;在文字生成中也是一样,输入一个向量能得到对应的语句。
基本形式就像下图一样:
一个Generation就是一个神经网络,更简单来说,就是一个方程,输入一个向量,就能得到一个更高维度的向量,将其进行通道,图片尺寸进行重组后就是一张新的图片。
以图像生成为例,通常输入向量的每一个dimension会对应到图像的某一个特征,比如头发长度,眼镜大小,颜色等。
Discriminator
Discriminator也是一个神经网络,或者说方程,输入一张图片(或者一个句子),输出一个数值,这个数值越大,则说明这个输入的真实性越高。比如说下面这张图片所示:
Generation vs. Discriminator
在GAN中这两个神经网络可以看作是一种对抗的关系,比如说在第一个Generation中生成了一组图像,然后Discriminator根据某一个判断标准比如说图像是不是彩色的来判断这组图像是否足够真实;然后第二个Generation根据第一个Discriminator的结果产生了一组新的彩色图片,然而第二个Discriminator又根据另一个判断标准比如是否有眼睛来判断这组图片是否足够真实;再接着第三个Generation又根据第二个Discriminator的结果……这样一直“对抗”下去,直到生成的图片可以骗过Discriminator的时候,就完成了。
Algorithm
根据上面它们两者的关系就可以大致写出这个算法的流程了:
- 初始化generator和discriminator
- 进入循环,每个循环进行如下步骤:
step-1:固定住generator G,更新discriminator D(再说具体一点的话就是,用当前的G产生一组图片,在D中与真实的图片(已有的database)作对比,训练D,使真实图片高分,生成图低分。)
step-2:固定住D,更新G(具体就是,把一个向量输入进G,产生一张图片,根据当前的D进行评分,训练G,使得到比较高评分)
(一般来说是把G和D一起当作是一个巨大的神经网络,即输入向量得到一个数值)
说得再具体一点就是:
- 初始化 D D D和 G G G的参数分别为 θ d \theta_d θd和 θ g \theta_g θg;
- D D D的学习过程:
( a ). 从数据集database中选取 m m m个样本 { x 1 , x 2 , . . . , x m x^1,x^2,...,x^m x1,x2,...,xm};
( b ). 从一个分布(高斯或均匀或其它)中采取 m m m个噪音样本 { z 1 , z 2 , . . . , z m z^1,z^2,...,z^m z1,z2,...,zm},其中噪音样本维度自己定,属于超参数;
( c ). 利用 G G G获取生成数据 { x ~ 1 , x ~ 2 , . . . , x ~ m \widetilde{x}^1,\widetilde{x}^2,...,\widetilde{x}^m x 1,x 2,...,x m}, x ~ i = G ( z i ) \widetilde{x}^i = G(z^i) x i=G(zi);
( d ). 更新 D D D的参数 θ d \theta_d θd,以便最大化 V ~ \widetilde{V} V ,其中: V ~ = 1 m ∑ i = 1 m log D ( x i ) + 1 m ∑ i = 1 m log ( 1 − D ( x ~ i ) ) \widetilde{V}=\frac{1}{m}\sum_{i=1}^m\log D(x^i)+\frac{1}{m}\sum_{i=1}^m\log(1-D(\widetilde{x}^i)) V =m1i=1∑mlogD(xi)+m1i=1∑mlog(1−D(x i)) (简单说一下这个 V ~ \widetilde{V} V ,第一项就是让真实图片的得分越大越好,第二项就是让生成的图片得分越小越好,其中 D ( . ) D(.) D(.)一般是经过sigmoid的介于0~1的数) θ d ← θ d + η ∇ V ~ ( θ d ) \theta_d \leftarrow \theta_d + \eta \nabla \widetilde{V}(\theta_d) θd←θd+η∇V (θd)(这里在说一句,一般这里更新不会是只update一次的,至于更新几次也属于超参数,要自己调的)- G G G的学习过程:
( a ). 另外从一个分布(高斯或均匀或其它)中采取 m m m个噪音样本 { z 1 , z 2 , . . . , z m z^1,z^2,...,z^m z1,z2,...,zm};
( b ). 更新参数 θ g \theta_g θg以最大化 V ~ \widetilde{V} V ,其中 V ~ = 1 m ∑ i = 1 m log ( D ( G ( z i ) ) ) \widetilde{V}=\frac{1}{m}\sum_{i=1}^m\log(D(G(z^i))) V =m1i=1∑mlog(D(G(zi))) θ g ← θ g + η ∇ V ~ ( θ g ) \theta_g\leftarrow\theta_g+\eta\nabla\widetilde{V}(\theta_g) θg←θg+η∇V (θg)上面2,3步骤反复执行。
补充
GAN可以看作是一个Structured Learning的方法,基本可以看作下面两个部分组成:
Bottom Up 是指一个一个部件生成的办法,这种方法会失去全局观,也就是说不知道各个部件之间的联系;下面的Top Down 是直接观察整体,然后进行判断,generator没法用这种方法。
问题1:能不能不用Discriminator?
严格说来是可以的,用Auto-encoder的技术,但由于同个layer神经元之间没有联系,为了让它们产生联系,就必须多加layer,这样会把神经网络弄得很复杂,所以在同种效果下,GAN的技术会更实用。
问题2:能不能不用Generation, 就只用Discriminator来做生成?
也是可以的。但也很麻烦,要穷举所有可能的 x x x,使 x ~ = arg max D ( x ) \widetilde{x}=\argmax D(x) x =argmaxD(x)然后还要让Discriminator学会如何分别好的和坏的图片,但实际上我们的database里只有好的,不过这个问题有办法解决,如下:
- 随机产生一些坏的图片,比如随机噪音;
- 用好的图片和坏的图片去训练 D D D;
- 用当前 D D D产生一组新的图片,充当坏的图片继续与好的图片去训练 D D D
步骤2-3循环。
效果如下:
所以实际可以这么理解,generator就是用来解
arg max
\argmax
argmax问题的,也就是用generator产生坏的图片。
两者比较
Generator:
优点:
1. 容易生成东西。
缺点:
1. 不容易考虑部件(component)之间的关系;
2. 只是模仿表象。
Discriminator
优点:
1. 考虑整张图片。
缺点:
1. 不容易生成东西;
2. 解那个 arg max \argmax argmax问题不容易。