关于mode collapse的学习日志

2019.8.29

终于开始接触机器学习相关的项目了,和博士师兄谈话后发现项目是GAN,安心了一点,GAN也是自己之前接触过的。
之前只知道GAN生成出来的结果多样性少,在pix2pixHD和vid2vid中都用了语义编辑的办法增加多样性。
今天得知了一个新词"mode collapse"(模式坍塌),指的是生成器产生的结果很单一,仅仅只是为了得到最低的判别器损失D_loss,却忽视了数据集的分布。
根据今天的谈话内容整理以下待解决的问题

1.感觉自己的数学基础还比较欠,要多找找相关知识的帖子补补课

2.深入了解**mode collapse**,自己找找看目前有哪些解决坍塌的办法

3.信息论中的**熵**表示混乱程度,infoGAN和mode collapse怎么联系起来?

4.让我看**苏剑林的博客**,先看吧,然后自己再搜搜相关的博客和论文,找不到只好再问师兄了。

2019.8.30

先找了相关的博客,把熵的概念和相关公式重新学习了一遍,发现这些都是之前学过的,不过又给忘了,这次记录下来吧。

1.决策树

从决策树入手,看了下感觉这东西不就是个树么,根据属性进行分类。。。似乎没什么难的,大概看看就算了吧。

2.熵

然后是学习熵的相关公式。
相关资料:
机器学习理论篇1:[机器学习的数学基础]
Bin的专栏

看完过后自己的感觉是,熵其实就是记录某个信息所需要的最短字节数,然后它还表示了混乱程度(我把它理解为分布均匀不均匀)。
例子:假如一个随机变量x有8种可能的状态,每一种都有相同的概率。传输该变量我们至少需要3个bits(2^3=8),或者可以用熵来刻画,

这里需要注意的是:条件熵、熵、互信息的关系,后面会用到

3.GAN中的mode collapse

相关资料:
能量视角下的GAN模型(一):GAN=“挖坑”+“跳坑”
能量视角下的GAN模型(二):GAN=“分析”+“采样”
首先我们知道GAN就是G和D的对抗博弈,G会仿照真实样本的分布p (即X~p(x)),生成一个假的分布q,上面资料中的博主以能量的视角描述了这个问题,但是这些我之前已经懂了,就不再记录了。
需要记录的是以下内容:
首先学习到mode collapse就是模型只能生成单一样式的样本(生成器产生的图片都几乎一个样子)
在这里插入图片描述
在这里插入图片描述
所以这样就把熵和mode collapse结合起来了,H(G(Z)) 代表了假样本的熵,熵越大,那么GAN在优化的时候理论上就不会存在所有的假样本都优化到同一个点的问题了。

记得互信息、熵、条件熵的关系,可以把熵转化为互信息
在这里插入图片描述
在这里插入图片描述

虽然已经有方法可以直接估计互信息,方法在《深度学习的互信息:无监督提取特征》的“互信息本质”一节
公式推导不太看得懂,直接贴个loss的计算方法

全局互信息loss:

在这里插入图片描述

局部互信息loss:

在这里插入图片描述
贴了公式有什么用呢,我还是不会算,再贴个作者实现的开源代码
除了估计互信息,还可以最大化互信息的下界。看公式看得我晕了,直接写个结论吧:

相当于在生成器加入一项loss,

在这里插入图片描述
原作者的开源实现:https://github.com/ritheshkumar95/energy_based_generative_models

2019.8.31

写的博客忘记保存了,唉。。。根据前后文推断补一下今天的日记吧,31号应该是在研究没看完的公式,然后差不多搞懂理论的前因后果和推导过后接触代码,具体看模型怎么构造的。
刚接触的时候完全不懂写的代码和公式有一毛钱关系么???很迷茫,慢慢确定了每个net是拿来干嘛的,但是完全没明白互信息咋算的。

2019.9.2

今天继续看了原作者的代码实现,基本看完了,每个net干了什么事也差不多明白了,但是依然没太明白互信息是怎么计算的,感觉和公式写的不是一个东西。好在博士师兄说当成黑盒子不用管,开心的跳过。明天继续看剩下的代码是怎么实现的。

2019.9.3

虽然昨天说当成黑盒子不用管,但是我是真的有点倔,又去看了。
今天突然发现在互信息估计里面作者说了一句话,“其实(12)式的含义非常简单,它就是“负采样估计”:引入一个判别网络σ(T(x,z)),x及其对应的z视为一个正样本对,x及随机抽取的z则视为负样本,然后最大化似然函数,等价于最小化交叉熵。”在这里插入图片描述
(12)式算的其实就是JS散度度量的互信息,因为KL散度是无上界的,这使得我们无法对其进行优化(优化到正无穷)。再回过头来看训练生成器的代码,突然感觉是这么回事。

def train_generator(netG, netE, netH, optimizerG, optimizerH, args, g_costs):
    netG.zero_grad()
    netH.zero_grad()

    # z = MALA_corrected_sampler(netG, netE, args)
    z = torch.randn(args.batch_size, args.z_dim).cuda()
    x_fake = netG(z)
    D_fake = netE(x_fake)
    D_fake = D_fake.mean()

    ################################
    # DeepInfoMAX for MI estimation
    ################################
    label = torch.zeros(2 * args.batch_size).cuda()
    label[: args.batch_size].data.fill_(1)

    z_bar = z[torch.randperm(args.batch_size)]
    concat_x = torch.cat([x_fake, x_fake], 0)
    concat_z = torch.cat([z, z_bar], 0)
    mi_estimate = nn.BCEWithLogitsLoss()(netH(concat_x, concat_z).squeeze(), label)

    (D_fake + mi_estimate).backward()  # D_fake其实就是判别器损失,mi是互信息估计

    # 引入一个判别网络netH,x及z视为一个正样本对,x及z_bar则视为负样本,然后最大化似然函数,等价于最小化交叉熵。

    optimizerG.step()  # 优化生成器
    optimizerH.step()  # 优化编码器

    g_costs.append([D_fake.item(), mi_estimate.item()])

concat_x和concat_z上下对应了x+z(正样本),x+z_bar(负样本),然后算一个交叉熵,最后对这个判别网络H进行优化。虽然来龙去脉还是不太清楚,但是现在好歹把公式和代码对应上了!

然后对应能量网络(判别器)的代码,也可以完美的和公式对应上:在这里插入图片描述

def score_penalty(netE, data, beta=1.):
    data.requires_grad_(True)
    energy = netE(data) * beta
    score = torch.autograd.grad(
        outputs=energy, inputs=data,
        grad_outputs=torch.ones_like(energy),
        create_graph=True, retain_graph=True, only_inputs=True
    )[0]
    return (score.norm(2, dim=1) ** 2).mean()

def train_energy_model(x_real, netG, netE, optimizerE, args, e_costs):
    netE.zero_grad()

    D_real = netE(x_real)
    D_real = D_real.mean()  # 对应第一项

    # train with fake
    # z = MALA_corrected_sampler(netG, netE, args)
    z = torch.randn(args.batch_size, args.z_dim).cuda()
    x_fake = netG(z).detach()
    D_fake = netE(x_fake)
    D_fake = D_fake.mean()  # 对应第二项

    penalty = score_penalty(netE, x_real)  # 对应第三项
    (D_real - D_fake + args.lamda * penalty).backward()  #整个loss

    optimizerE.step()

    e_costs.append([D_real.item(), D_fake.item(), penalty.item()])

EBGAN小结:

既然代码和公式都已经全部搞懂了那就把整个思路再梳理一遍:
1.首先采用了能量模型来对GAN进行诠释,我们想把所有的真实样本都放在势能最低的点,用这个能量曲线来拟合真实的样本分布曲线。假设我们的能量模型已经很完美了,那么对于不在最低点的样本我们都可以当作假样本。这个想法非常符合判别器的设定,只是换了一种方法诠释。
2.我们知道GAN除了训练不稳定、梯度消失的问题外,还有个mode collapse的问题。通俗来说就是生成器学习到了某种特征可以欺骗判别器,然后生成器就一直生成这种特征的图片以获取判别器的高评价,导致生成结果单一,生成样本分布可能只是真实样本的一部分,就像真实分布被折叠了一样。
3.在这里插入图片描述
4.接下来需要提到的是一个采样的问题,为了方便采样,用qφ(x) 拟合qθ(x)。并用KL散度度量这两个分布的差异。经过一番推导,我们发现,我们的优化目标是这样的。−Hφ(X) 希望熵越大越好,这意味着多样性;Ex∼qφ(x)[Uθ(x)]希望图片势能越小越好,这意味着真实性
在这里插入图片描述
其实分别就是判别器的优化目标和生成器的优化目标。

5.剩下的问题就只有H(x)怎么算的问题了。我们知道互信息=熵+条件熵,然后对于我们的x=Gφ(z),经过推导发现我们的条件熵其实是个常数,所以,总的来说我们可以确定互信息Iφ(X,Z)与熵Hφ(X)只相差一个无关紧要的常数,所以在式(15)中,可以将Hφ(X)替换为Iφ(X,Z)。那么就把熵的计算转换成了互信息的计算了,互信息的具体计算方法参考互信息估计,在上文中的代码分析中也分析了公式和对应代码实现。

WGAN

还学习了WGAN,学习过程写在了另一篇博客

待解决、学习:

1.在理解了GAN存在的一些饱受诟病问题(不收敛、模式崩塌、梯度消失)后,我们需要完成的是如何解决mode collapse的问题。在能量GAN中我们看到可以用互信息计算,新的方法呢?

2.继续学习以下的paper:

a. 万字综述之生成对抗网络(GAN),这个是为了深刻理解GAN

b. 全面解析Inception Score原理及其局限性

c. CycleGAN:图片风格,想换就换   ICCV 2017论文解读,这个不是CGAN

d. 详解GAN的谱归一化(Spectral Normalization),这个是重点

e. MGAN。

2019.9.4

今天主要看的是万字综述之生成对抗网络(GAN)
这篇文章主要是对设计到GAN的知识做了个综述。比如千差万别的GAN模型,有什么相似、不同之处呢?分别解决了什么问题呢?存在什么问题呢?

在这个万字综述中,主要学习到的就是一个整体的了解。什么EBGAN,VAE,AutoEncoder,谱归一化,Lipschitz 约束,WGAN,KL\JS散度,CGAN等等都有提到。前半部分我有逐字逐句的看,后面的东西了解的稍微少点,感觉也不是那么重要,就跳过了。

看完后再联想到meeting中讲到的idea,感觉自己需要重点了解谱归一化(据说是每层都加WGAN的Lipschitz约束),还有MAD-GAN(多个生成器),然后就是Inception Score(评价指标,但是完全不了解)

2019.9.5

Spectral Normalization学习心得:

在WGAN中学习到用Wasserstein距离来度量生成分布和真实分布的差距,并且采用了clip的方式约束判别器参数,使其满足1-Lipschitz continuity。这里用的是另一种方法让判别器满足1-Lipschitz continuity。

对神经网络而言,矩阵乘法是线性运算,所以如果让每一层的参数都是 1-Lipschitz continuity,那么整个判别器就是 1-Lipschitz continuity的。

经过一些公式的推导(略,见链接)可以得出了这样的结论:矩阵 A 除以它的 spectral norm(A转置乘A的最大特征值开根号)可以使其具有 1-Lipschitz continuity。所以目的转化为求A_T*A最大特征值的开根,也就是最大奇异值。

但是如果通过矩阵分解去算,运算量太大,有一种估算的方法Power iteration ,Power iteration是用来近似计算矩阵最大的特征值(dominant eigenvalue 主特征值)和其对应的特征向量(主特征向量)的。

计算方法见标题链接。这里简而言之,经过很多次的u、v的交替迭代,可以算出来W的最大奇异值,然后再用它对W进行归一化。代码点这里

## Inception Score原理及其局限性学习心得

大部分人在看paper的时候会直接先看实验结果部分,如果实验结果很一般,不管理论说得多么天花乱坠,数学公式多么浮夸都没用。所以就会需要评价模型的指标。

对于GAN这种生成模型来说,有一种指标叫做Inception Score,首先说一下它的大概原理吧。Inception Score 是这样考虑清晰度和多样性的:

  1. 清晰度:把生成的图片 x 输入 Inception V3 中,将输出 1000 维的向量 y ,向量的每个维度的值对应图片属于某类的概率。对于一个清晰的图片,它属于某一类的概率应该非常大,而属于其它类的概率应该很小(这个假设本身是有问题的,有可能有些图片很清晰,但是具体属于哪个类却是模棱两可的)。用专业术语说, p(y|x) 的熵应该很小(熵代表混乱度,均匀分布的混乱度最大,熵最大)。

  2. 多样性:如果一个模型能生成足够多样的图片,那么它生成的图片在各个类别中的分布应该是平均的,假设生成了 10000 张图片,那么最理想的情况是,1000 类中每类生成了 10 张。转换成术语,就是生成图片在所有类别概率的边缘分布 p(y) 熵很大(均匀分布)。

存在的问题如下:

1. Inception Score 对神经网络内部权重十分敏感:不同的框架中的预训练Inception V3分类效果差不多,但是由于权重有细小的区别,算出来的IS差别较大。 

2. 计算 Inception Score 的方式不对:把input分为不同的份数,得到的分数是不同的。 

3. 分类模型和生成模型在不同的数据集上训练。 

4. 直接优化这个 Inception Score,会导致生成对抗样本。 

5.  没有反映过拟合。 

cycleGAN

还看了cycleGAN,其实就是A->B的GAN加上B->A的GAN,效果特别好,但是使用的依然是比较传统的loss和结构。

最后一个需要看得是MGAN,明天再研究。

小总结:

目前看来这些文献不管是loss function还是评价指标都是和计算分布的距离高度相关的

2019.9.6

今天首先看了MGAN的论文:MGAN: TRAINING GENERATIVE ADVERSARIAL NETS WITH
MULTIPLE GENERATORS

草草浏览了一下,没有细致看,因为我觉得没有眼前一亮的感觉(我飘了…)。
MGAN的主要贡献如下:

  1. 提出了一种新颖的模型,就是多个生成器
  2. 在最小化生成分布和真实分布的JS散度时,最大化各个生成器的JS散度(换句话说就是让每个生成器都不一样,但是生成分布是符合真实分布的)

所以MGAN就用多个生成器的方法来解决了mode collapse的问题。

接下来阅读的paper是VEEGAN: Reducing Mode Collapse in GANs using Implicit Variational Learning

在这里对作者的方法进行一个直观解释:

  1. VEEGAN设计了一个reconstructor network F θ F_\theta Fθ 用于“反转”生成器网络 G γ G_\gamma Gγ 。这个重构网络作用于 G γ ( z ) G_\gamma(z) Gγ(z)得到 F θ ( G γ ( z ) ) F_\theta(G_\gamma(z)) Fθ(Gγ(z)),并衡量 F θ ( G γ ( z ) ) F_\theta(G_\gamma(z)) Fθ(Gγ(z)) z z z 的L2距离。
  2. 同时为了验证 F θ F_\theta Fθ 的效果,将 F θ F_\theta Fθ 作用于训练数据 x x x上,计算 Z Z Z F θ ( x ) F_\theta(x) Fθ(x)的交叉熵来验证 F θ ( X ) F_\theta(X) Fθ(X)是否为真实分布到高斯分布的映射。
  3. 最终的优化目标就是,公式如下:
    在这里插入图片描述

因为计算困难,最小化上式变为最小化上式的上界,转化有较多公式,我也没太看懂,这里直接写结论吧。
在这里插入图片描述
其中前两项是 H ( Z , F θ ( X ) ) H(Z,F_\theta(X)) H(Z,Fθ(X))的上界,第三项是 F θ ( G γ ( z ) ) F_\theta(G_\gamma(z)) Fθ(Gγ(z)) z z z 的距离,这就是我们的优化目标

然后因为KL距离又难计算,引入判别器。

判别器定义如下。根据原文,这个判别器是为了估计一个叫做”density ratio“的东西。
在这里插入图片描述
注意上面的优化目标的第二项是常数,被忽略掉。最终优化目标转换为
在这里插入图片描述
然后对于Dw的优化目标如下。
在这里插入图片描述
其实后面的公式,对我来说有点超出理解范围了,没太看懂。不过总体来说,后面的公式都是计算、优化方法吧。

核心思想,我的理解,就是是用一个网络来衡量重构误差,这个重构误差体现了生成器产生的分布是否接近真实分布。

2019.9.9

过了一个周末,今天继续看看VEEGAN的实验。

因为真实图片我们无法知道其分布,就没法评估,所以作者在合成图片的数据集上做实验。然后它的数据集其实我没太看懂怎么回事,结果就是一共有3个合成数据集,分别是8个2d高斯分布排列成环状,25个2d高斯排列成网格,以及10个700维高斯分布嵌在1200维空间中。

然后对其进行mode个数的统计,以及对应的高质量百分比。
在这里插入图片描述
比如对于2D Ring GAN,我们看到它有99.3%的高质量,但是这是因为它只生成1种mode,对应下图b。

再比如2D Grid Unrolled,他有23.6种模式(接近最大值25),但是这是因为它只追求分布的离散,因此只有16%的高质量,对应下图i。
在这里插入图片描述
下表在stacked MNIST上的测试结果,VEEGAN捕获了最多的mode,同时有最小的KL散度。
在这里插入图片描述

2019.9.10

目前所阅读的文献、方法总结:

  1. EBGAN:基于能量的GAN,主要是把GAN中的真假样本用了能量的视角去处理。另外,在loss function中,为了解决mode collapse的问题,计算了假样本的熵,希望假样本分布混乱、均匀。然后又用了转化成互信息的方法去计算熵。
  2. WGAN:Wasserstein GAN,顾名思义,这是用了Wasserstein距离来度量生成分布和真实分布的距离。原始GAN的优化目标可以等价表示为KL散度-2*JS散度,这个优化目标首先是JS散度前面的负号,让这个优化目标奇怪(到底是远离还是靠近)。然后是KL散度存在的问题,KL散度不对称,对于没能生成真实样本(多样性缺失)和生成了假样本(准确度缺失)的惩罚差距巨大,使得生成器愿意生成单一的样本导致mode collapse。引入Wasserstein距离,可以使得没有重叠的分布依然可以计算出“非突变”、‘对称“、”稳定“的距离,度量两个分布的区别。梯度消失的问题也随之解决,训练GAN不再需要小心翼翼,同时loss可以作为训练的指标,来观察训练的进度。Wasserstein距离直接计算有困难,但是如果是K-Lipschitz continuity就可以转化成好计算的形式。另外WGAN使用了一个clip的方法。
  3. Spectral Normalization:谱归一化,更加偏向矩阵理论,大概是说一个矩阵的每个元素都除以最大奇异值,就能实现谱正则化,进而具有 1-Lipschitz continuity。如果让神经网络每一层的参数都是 1-Lipschitz continuity,那么整个判别器就是 1-Lipschitz continuity的。有1-Lipschitz continuity,就可以算Wasserstein距离。算是对WGAN的补充。
  4. Inception Score:一种衡量生成模型效果的指标,主要由清晰度和多样性决定。其实是个分类器?如果分类明确就说明清晰度高;如果每个类别生成的图片数量都差不多,就说明多样性高。但是它有很多局限性比如:1. Inception Score 对神经网络内部权重十分敏感:不同的框架中的预训练Inception V3分类效果差不多,但是由于权重有细小的区别,算出来的IS差别较大。 2. 计算 Inception Score 的方式不对:把input分为不同的份数,得到的分数是不同的。 3. 分类模型和生成模型在不同的数据集上训练。 4. 直接优化这个 Inception Score,会导致生成对抗样本。 5. 没有反映过拟合。
  5. MGAN:多生成器GAN,其优化方法是,最小化生成分布和真实分布的JS距离,同时最大化各个生成器之间的JS距离。
  6. VEEGAN:使用了一个重构网络,是生成网络的反,代表着真实(生成)分布到高斯分布的映射。通过衡量 F θ ( G γ ( z ) ) F_\theta(G_\gamma(z)) Fθ(Gγ(z)) z z z 的距离,以及 Z Z Z F θ ( x ) F_\theta(x) Fθ(x)的距离,可以优化生成器G。

2019.9.11~2019.9.15

中秋节之前开始跑mode seeking的代码,想验证MSGAN的效果。

DCGAN的因为是CIFAR10,数据小很多,很快跑完了。这里贴一个图,是tensorboard截图。说实话32*32的图,能看出啥来啊…
在这里插入图片描述

但是中秋节的时候实验室服务器好像是断电了还是没网了怎么,训练终止了。DRIT mode seeking的那个比较慢,作者实验结果的2000个epoch只跑了1000个。图片质量看起来还是很不错的,也贴个tensorboard截图,但是好像跟mode collapse没有一毛钱关系啊。

这上千行没注释的代码着实难搞,我甚至没看懂这每行图片从左到右分别代表什么。
对第一行猜测(第二行相反):第一列是真实图片real_A_encoded,第二列到第四列都是fake_B_encoded\random,第5列是fake_AA_encoded,最后一列是重构图片。
在这里插入图片描述

2019.9.16

今天继续在研究MSGAN的代码,同时开始阅读师兄发给我的新文章:VGAN
代码在Github

VGAN是跟互信息计算相关的一种GAN网络。

首先是目标函数
在这里插入图片描述

我们计算I(X,Z),并且引入encoder E作为X到Z的映射,I(X,Z)最后转换为
这里插入图片描述
注意我们的不等式条件是I(X,Z)<=Ic,直接计算上面这个积分会很困难,所以转为计算这个积分的上界,让这个上界小于Ic就行。最后这个积分被表示为KL散度在x~p(x)上的期望。
在这里插入图片描述
因此我们的目标函数变为
在这里插入图片描述
然后引入一个参数,得到如下的目标函数
在这里插入图片描述
接下来考虑标准GAN的优化问题
在这里插入图片描述
同样采用一个Encoder,将对x的判别,改为对隐层z的判别,并加入互信息<=Ic的限制
在这里插入图片描述
同样将限制条件乘上拉格朗日乘子,得到对应的目标函数,如下所示(参考深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件
在这里插入图片描述
使用以下的更新方法来更新判别器、Encoder、拉格朗日乘数
在这里插入图片描述
其中 α β \alpha_\beta αβ是更新 β \beta β的步长。第一行的{\cal ABCDE}就是拉格朗日函数,即下式
在这里插入图片描述
注意参数更新中,我们更新的参数是D,E, β \beta β,既然是GAN,当然有G,目标函数如下,注意到在G的目标函数中,用的是 D ( μ E ( x ) ) D(\mu_E(x)) D(μE(x)),而不是常见的 D ( G ( z ) ) D(G(z)) D(G(z))或者 D ( x ) D(x) D(x)
在这里插入图片描述
效果图:
在这里插入图片描述
在这里插入图片描述
VGAN总结:
使用了信息瓶颈,让判别器可以关注于更加有效的特征,让判别器工作的更好,进而解决梯度消失问题。

  • 12
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值