0%

李宏毅深度学习-15-生成网络

视频来源:https://www.bilibili.com/video/av9770302/?p=15

1 前提概览

生成网络可以做什么? 写诗,画动漫头像。

1.1 Auto-encoder

通过encoder将一张图片变成一个 code vector,然后用一个decoder将此code vector 生成一张图像。它们训练时时联合训练,训练完成之后,可以用decoder来生成一张图片。

1.1.1 实例

生成一个手写字生成的decoder,其生成的coder vector假设会2维的,如下:

接着,我们输入一个二维向量,假设为 [1.5,0],可能生成的手写字是0。假设我们输入一个二维向量 [1.5,0]生成的手写字可能是1。如下图:

如果,二维向量的值在[1.5,0][1.5,0]之间等距离取值的话,可能得到如下的结果

但是auto-encoder无法生成state of art的结果。

1.2 VAE(Variational Auto-Encoder)

VAE是一个进阶版的auto-encoder,训练的时候,输入一张图片,但是它同时输出三个vector,假设这三个vector都是3维的,如下图:

其中的m1,m2,m3代表VAE的encoder的输出code,只不过是个三维vector。同时还会生成另外一个三维的vector σ1,σ2,σ3,同时会随机从一个符合正态分布的数据集中sample一个三维vector e1,e2,e3 (称为noise)。接下来做如下操作:

  1. 将vector σ1,σ2,σ3 指数化
  2. 将第一步指数化之后的值与noise vector e1,e2,e3 相乘
  3. 将生成的code vector m1,m2,m3与第二步的结果相加,得到结果 c1,c2,c3

再将最后的结果 c1,c2,c3 输入到decoder网络训练,整个过程如下:

1.2.1 VAE的受限条件

在训练VAE时由于添加了额外的项 σ,则需要添加一个受限条件(假设),即需要最小化:

3i=1(exp(σi)(1+σi)+(mi)2)

其中 (mi)2 可以看做L2 正则,而最小化 exp(σi)(1+σi) 部分即最小化 σi,当它为0时,这部分的值最小。

1.2.2 VAE的问题

我们期望的VAE是它能生成与真实图像越接近越好的图像

但实际上VAE实际模拟过程与人类的有出入,下图蓝色框代表了两种可能出现的情况。很显然,人类可以分辨出左边是比较接近真实的,右边的不那么接近的(黄色框),但是对于VAE(蓝色框)来说它们在损失函数面前是等价的。

1.3 evolution of generation

上图是一个示例,分别迭代多次,每次是一对 generatordiscriminator,不断演化,最后得到较好结果。其中的discriminator是一个二分类器,如果来自真实图像,则输出1,如果来自生成网络则输出0.

1.3.1 GAN中的Discriminator

Discriminatory本质上是一个二分类分类器,输入一张图片,它会判断该图片是real(1)还是fake(0)。

1.3.2 GAN中的Generator

GAN中的Generator与VAE中的decoder类似,输入一个随机的vector,输出一些图片。与VAE不同的是,在训练VAE的时候需要最小化一个重构误差

此处GAN中Generator的架构与VAE一样,只是在训练时方法不一。

首先,我们有个所有参数都是随机产生的generator。此时输入一组参数随机的向量,generator会产生一组假的图像;同时从训练数据集中随机抽取一组真的图像,然后将所有假的图像标签标记为0(negative sample),所有真的图像标记为1(positive sample)

1.3.3 GAN 过程

首先随机输入一组向量给Generator,产生一组图像,Discriminator知道这个是假的图像,会输出一个很低的置信度。

接下来,需要更新generator参数,它会产生的图像让第一代的Discrimintor觉得它是真的图像,输出1。

注意,我们在训练过程中会固定 Discriminator,使用随机梯度更新Generator

二 GAN的核心思路

2.1 最大似然估计

  • 给定数据分布 Pdata(x),此处的x就想象成一张图片的所有的像素值串起来。
  • 现在我们要找到一个数据分布PG(x;θ),它受控于一组参数θ的。
    • 其中PG(x;θ)是一种数据分布,比如可以是高斯混合模型。其中θ代表了高斯分布的期望和方差这两个参数。只不过在GAN中PG(x;θ) 是一个 神经网络。
    • 那么我们要做的事情就是,找到一个一组参数 θ,使得 PG(x;θ)的分布与Pdata(x) 的分布越接近越好。

Pdata(x)中抽样x1,x2,xm

如果给定参数θ 那么我们可以计算 PG(xi;θ)的值。

似然度:即给定参数θ时,从PG(xi;θ) 中抽样产生 x1,x2,x3xn的概率。似然度为 L=mi=1PG(xi;θ)

我们要做的其实就找一组参数 θ使得最大化 L的似然度。对于高斯混合 模型,参数就是均值、方差,以及混合权重。比如有下图的高斯混合模型,数据有三个高斯分布混合而成,如下:

该分布中均值即上图中三个黄色中心点,方差即三个圆形半径。

$$
\theta ^* = arg \quad max_{\theta} \prod ^m {i=1}P_G(x^i;\theta)=arg\quad max{\theta}\quad log \prod ^m {i=1}P_G(x^i;\theta)\quad 等同于求对数极大值\
= arg \quad max
{\theta}\sum ^m_{i=1}logP_G(x^i;\theta)\quad\quad 其中{x^1,x^2,…x^m}都是从 P_{data}(x)中抽样得到的 \
\approx arg\quad max_{\theta}\quad E_{xP_{data}}[logP_G(x;\theta)] \quad\quad 等同于从 P_{x{data}}分布中抽样 x^1,x^2,..x^n 然后计算每个 x^1,x^2,..x^n 使得 log P_G(x;\theta) 最大这件事 \
=arg \quad max_{\theta} \int x P{data}(x)logP_G(x;\theta)dx \
等同于 arg \quad max_{\theta} \int P_{data}(x)logP_G(x;\theta)dx-\int xP{data}(x)log P_{data}dx \
=arg\quad min_{\theta}\quad KL(P_{data}(x)||P_G(x;\theta)) \quad 【KL散度】
$$

在GAN之前,高斯混合模型生成的图像非常模糊,因为高斯混合模型无法真正模拟图像数据分布。

2.2 将 PG(x;θ) 换成一个神经网络

此时的GAN结构如下,输入通常为一个简单的 高斯分布的向量。经过神经网络 G(z) 之后输出x

关于神经网络 G(z) 的函数表达式可以表示为: $P_G(x)=\int xP{prior}(z)I_{[G(z)=x]}dzG(z)()xzz(P_{prior}(z))zG(z)xxxI_{G(z)=x}$判定,如果等同则为1,否则为0。

当前问题是,如果以这种方式计算。难以计算,给定x,即便我们知道输入分布z的参数,但是由于神经网络极其复杂,要想计算由网络生成x的概率会很困难。 在无法计算似然度的情况下,无法调整参数θ使得网络输出x接近真实数据分布。这个就是GAN的共享。

2.3 GAN的基本介绍

  • Generator G
    • G是一个函数,输入为Z,输出为x
    • 给定先验分布 Pprior(z) ,又得知函数G,我们可以定义一个概率分布 PG(x)
  • Discriminator D
    • D是一个函数,输入为x,输出为标量。
    • Discriminator D的作用就是衡量 PG(x)Pdata(x)的差异
  • 有一个函数 V(G,D),我们要找的最好的G。 G=argminGmaxDV(G,D)

2.3.1 如何理解 G=argminGmaxDV(G,D)

我们先看最右边的 maxDV(G,D) 部分。它的意思是选择使得 V(G,D)最大的 D,假设我们只有三个可能的G(G1,G2,G3,如下图),实际上由于G是一个神经网络,所以它有无数种可能。

下图中,分别对于不同可能的G,改变D,可以得到不同的 V(G,D)。对于G1,G2,G3maxDV(G,D)(最大值)就是下图中,红色点的值。

接下来再去寻找一个G使得 maxDV(G,D)最小的G,可以从上图(红色点)中看到,对于 G1,G2,G3其最大值,在为G3时它的最大值最小。

2.3.2 关于函数 V的定义

$V= E_{xP_{data}}[logD(x)]+E_{xP_G}[log(1-D(x))]$ ,先不用考虑此公式如何得来。

对于给定的G,maxDV(G,D)评估的是 PGPdata之间的差异,所以我们要寻找的是那个能使得 PGPdata差异最小的 PGPdata固定)。

  • 对于给定G,最优的D是可以最大化V的。其中V的形式如下:
    $$
    V=E_{xP_{data}}[logD(x)]+E_{xP_G}[log(1-D(x))]\
    =\int xP{data}(x)logD(x)dx+\int _xP_G(x)log(1-D(x))dx \quad \quad 期望等于概率的积分\
    =\int x[P{data}logD(x)+P_G(x)log(1-D(x))]dx\quad\quad 都是对x的积分,相同部分放一起
    $$

  • 对于给定x,最优化的V等价于最大化上式中括号中的
    PdatalogD(x)+PG(x)log(1D(x)) aDbD xPdataPG

  • 找到D能够最大化: f(D)=alog(D)+blog(1D),对该式子求极值的方法就是下面求导,取0得到。

df(D)dD=a×1D+b×11D×(1)=0 a×1D=b×11D a×(1D)=b×D D=aa+ba,b D(x)=Pdata(x)Pdata(x)+PG(x)

将各个D 显现在图中,如下:

红色顶点处即,不同的G,取得最大D的值。该点到水平轴(D)的距离就是V(G,D)的值,也即PG1Pdata的差异。

由上面的推导可知 D(x)=Pdata(x)Pdata(x)+PG(x)。而$V(G,D)=E_{xP_{data}}[logD(x)]+E_{xP_G[log(1-D(x))]}$。那么,其实我们带入得到:

$$
D^*(x)=\frac{P_{data(x)}}{P_{data}(x)+P_G(x)} \
=E_{xP_{data}}[log\frac{P_{data}(x)}{P_{data}(x)+P_G(x)}] + E_{xP_G}[log\frac{P_G(x)}{P_{data}(x)+P_G}] \quad 将求期望转换为求积分\
\rightarrow \int x log\frac{P{data}(x)}{P_{data}(x)+P_G(x)}dx +\int x P_G(x)log \frac{P_G(x)}{P{data}(x)+P_G(x)}dx \
下面就开始推导 KL散度了,这里就不推导了。推导完也记不住,也看不懂
$$

  • 那么对于给定G, $max DV(G,D)-2log2+2JSD(P{data}(x)||P_G(x))(JSD(P_{data}(x)||P_G(x))P_G和P_{data})JSD(P_{data}(x)||P_G(x))0,P_GP_{data}log2P_GP_{data}max _DV(G,D)[-2log2,0]$

  • 那么,那个G才是使得$max DV(G,D)P_G=P{data}$

2.3.3 具体算法

算法可以按照如下步骤循环:

  1. 给定一个初始的 G0

  2. 根据G0 找到一个 D0使得它可以最大化 V(G0,D)

  • 其中 $V(G_0,D^* 0)P{data}P_{G_0}(x)$之间的JS差异。
  1. 下一步,我们需要找一个新的 G,假若为 G1。它必须使得PdataPG0(x)之间的JS差异减小。可以通过求梯度的方法,
  • θGθGλV(G,D0)θG 。可以通过此公式计算得到新的 G1

  • 用新的 G1计算PdataPG1(x)之间的JS差异

  1. 再找下一个G2,使用同样的方式…

  2. 重复,不断去寻找新的G

2.3.4 实际如何操作

我们的loss函数是 $V=E_{xP_{data}}[logD(x)]+E_{xP_G}[log(1-D(x))]P_{data}$求积分的,但是实际情况是,{P_{data}}是所有可能图像的分布,是不可积分的。所以,我们做如下逼近。

  • 通过从 Pdata(x)中抽样 x1,x2,x3,xm来毕竟 Pdata可能的数据分布,同时从generator PG(x)中也抽样 ˜x1,˜x2,..˜xm

  • 那么我们求上面的$V=E_{xP_{data}}[logD(x)]+E_{xP_G}[log(1-D(x))]\tilde V=\frac{1}{m}\sum ^m_{i=1}logD(x^i)+\frac{1}{m}\sum ^m_{i=1}log(1-D(\tilde x^i))$ 。此式可以看做一个对二分类分类器的交叉熵损失函数。

    • 比如一个二分类分类器,假若其输出为D(x),那么我们就需要最小化其交叉熵,我们会这么做
    • 如果x是正样本,那么就需要最小化 logD(x)
    • 如果x是负样本,那么就需要最小化 log(1D(x))
  • 再回过来,D是一个参数为θ的二分类的分类器。我们从 Pdata(x)中抽取 x1,x2,xm作为正样本,从PG中抽样 ˜x1,˜x2,˜xm作为负样本。以上面讨论的结论可以将最大化V变成最小化 $L=-\frac{1}{m}\sum^m {i=1}logD(x^i)-\frac{1}{m}\sum ^m{i=1}log(1-D(\tilde x^i))$

2.4 GAN完整算法

  • 在每次算法迭代过程中,都会更新Discriminator和Generator

我们先看看学习Discriminator 部分,一般会重复K次,一次无法找到全局最优参数。

  • 从数据分布 Pdata(x)中抽样 x1,x2,xm
  • 从先验分布Pprior(z)中随机抽取噪声数据z1,z2,zm。注意此处的先验分布只是个普通的正态分布
  • 将先验分布抽样得到的z1,z2,zm喂入˜xi=G(z1),获取一批生成数据 ˜x1,˜x2,˜xm
  • 更新discriminator的参数 θd,可以使得下式最大
    • ˜V=1mmi=1logD(x1)+1mmi=1log(1D(˜x1))
    • 使用梯度下降方法计算 θdθd+λ˜V(θd)

再来看训练Generator部分,下面的部分通常只会更新一次。generator不能更新太多,否则会导致JS差异度无法下降(generator已经以假乱真了)。

  • 从先验分布Pprior(z)中随机抽取噪声数据z1,z2,zm。此处的随机噪声数据可以与上面训练Discriminator部分的随机样本值一样,也可以不一样

  • 更新Generator的参数 θg使得下式最小

    • $\tilde V = \frac{1}{m}\sum^m {i=1}logD(x^i)+\frac{1}{m}\sum ^m{i=1}(1-D(G(z^i)))$ 。可以看到此式,前半部分跟Generator无关
    • 再用梯度下降法去更新 Generator的参数:θgleftarrowθg+λ˜V(θg)

3 实际如何实现GAN

3.1 真实实现中,Generator的目标函数

从上面的讨论中,我们可以看到Generator会使得式子 $V= E_{xP_{data}}[logD(x)]+E_{x-P_G}[log(1-D(x))](generator)E_{x~-P_G}[log(1-D(x))]-log(D(x))log(1-D(x))线-log(D(x))log(1-D(x))$):

观察需要最小化的 log(1D(x)),在D(x)很小时,该曲线很平滑,在D(x)很大时该曲线很陡峭。 D(x)很小意味着,由Generator产生出来的x无法骗过Discriminator,Discriminator可以很容易认出。也即在训练的初始步骤,由generator产生的样本都集中在平滑部分,此时的log(1D(x))微分值很小,训练变得缓慢。此时,我们可以修改目标函数为
v=Ex PG[log(D(x))]

此式子效果等同于log(1D(x)),同时可以快速训练,在初始步骤微分值很大,在后续步骤变得很小,比较符合训练期待。

3.2 如何评估JS divergence(差异)

我们将discriminator的loss就是来衡量JS divegence,loss越大,divergence越大

图中分别衡量的三个Generator,分别训练了1个epoches,10个epoches,25个epoches。其中训练了25个epoches的generator已经几乎可以state of art了,但是用这些Generator去训练discriminator时,discriminator依然有十分高的准确率。

我们先看看目标损失函数 $max DV(G,D)=-2log2+2JSD(P{data}(x)||P_G(x))$ 导致这个问题的主要原因有以下几点

  • 我们在训练和调整到的时候,不是真正用积分去计算,而是通过抽样来拟合。现在假设我们有红色和蓝色两个椭圆的数据点分布,如下,但是因为我们是使用抽样的方式来代表数据分布:

即便Generator产生的数据样本与真实样本之间有重叠,但是由于Discriminator比较强,所以它依然能找到一条曲线将红色点和蓝色点区分开。如何解决这个问题?

  • 使得discriminator 变弱一点,少更新,加dropout。但是一个弱discriminator将导致JS divergence无法计算。
  • PGPdata都是高维空间数据,现在假设它们都是二维空间的,那么 PGPdata可以看做二维空间里面的两条直线,那么这两条之间的交集非常小,几乎趋近于零(如下两条直线)。

所以真实PGPdata的情况可能像下面这样演化:

可以看到在P_G_0P_G_{50}…到P_G_{100}之前,JS divergence都是log2,GAN没有演化的动力。

3.3 如何解决GAN无法优化的问题

  • 加入噪音数据。在discriminator的输入中加入一些人工噪音数据
  • 训练Discriminator时,将其label加噪音。比如有张图片是positive,现在随机替换图像的部分内容为噪音

加入噪音数据之后,原本交集非常少PGPdata就可能会拓宽。如下:

注意:噪音数据要随着训练的推荐,逐步减小

4 mode collapse

比如有真实的数据分布为蓝色,而generator生成的数据分布为红色。如下左图,右边是对应生成的图像。

现在问题是,我们只知道GAN生成了的数据,无法知道GAN没有生成的数据。

假设当前Pdata的数据分布如下,为8个黑点。

但是,我们训练过程中会出现不一致的情况。比如,我们期望PG可以慢慢去覆盖Pdata,但是实际训练时PG一直只产生一个数据分布,不断去调整,但始终无法覆盖所有的Pdata

可能的原因是之前的损失函数定义,即KL divergence定义有误。下图左边代表了原始的损失函数定义

其中 KL=PdatalogPdataPGdx,当Pdata有值,而PG没有值的时候,该函数将取无穷大的值。所以此时GAN会尽力去覆盖尽可能多的Pdata的数据。

而看上图右边,KL divergence的倒数,ReverseKL=PdatalogPGPdatadx。此时当PG有值,而Pdata没有值得时候函数取值会趋近无穷大,此时为了避免出现这种情况,PG会尽可能拟合一个数据分布(假设真实的Pdata由多个分布组成的话)。

5 condintional GAN

与GAN不同的时,我们想生成制定的东西,此时的Generator输入就不止一个先验分布(正态分布)了。如下:

但此时可能会出现一个问题,generator可能会无视先验分布(PZ),generator会觉得先验分布只是个噪音数据,解决办法是在generator里面添加 dropout。

此时训练Discriminator也不一样,它的输入不再是一张图片,而是一张图片以及对应的描述,而对应的label则根据正负样本区别对待。

  • 正样本: (ˆc,ˆx),其中ˆc为图像真实描述,ˆx为真实图像。
  • 负样本: (ˆc,G(ˆc)),(ˆc,x)。其中ˆc为真正的图像描述,而G(ˆc)generator\hat c。同时要有另外一种fake sample,给discriminator真实的图像,但是给错误的描述。比如此处的ˆx为真实图像,但是ˆc为错误描述。

Related Issues not found

Please contact @shartoo to initialize the comment