本文内容绝大部分出自 台大李宏毅老师。
谢谢老师的悉心讲解。
GAN的介绍
- 生成
由 随机噪声向量,生成 图像、文本
Basic Idea of Gan
在图像生成当中,使用一个vector 来生成一个 高纬度向量(图像)
其中输入向量的各个维度潜在影响着图像某些风格。 比如 第一维影响头发长度,,倒数第二维度控制头发颜色,最后一维度控制张嘴
判别器:输入图像,输出标量
∈
[
0
,
1
]
\in [0, 1]
∈[0,1] 代表图像质量,数值越大表示越接近真实图像质量
一开始 生成器生成的图像非常差,判别器的判别,生成器会变强,骗过判别器。 然后判别器再学习如何判别,令自己变强。
训练算法
一些GAN训练的例子
-
随着训练,生成结果逐渐变好,生成器在挖掘从随机噪声生成dataset样本中的分布
-
缓慢改变输入向量,生成图像逐渐发生变化
gan能够挖掘到向量维度对生成结果的影响,看到改变输入,产生的输出脸的朝向不同
结构学习
机器学习是去寻找一个映射函数,
回归: 输出一个标量
分类:输出一个类别 (one hot 向量)
结构学习/预测: 输出一个序列、矩阵、图、树 等
输出序列
输出矩阵
- 生成器 能否自己进行学习
与分类器正好反过来
构建一个有监督训练环境
但是我们无法控制什么向量生成什么图像,以及向量维度和图像内容之间的关系。
利用auto encoder 可以获得编码向量,解码器可以作为生成器
训练好后 把 decoder分离出来:
发生了有趣的事情,改变二维输入向量,结果,x1控制了数字,x2控制了角度
但是当进行差分输入的时候,auto encoder模型只联系到输入到输出的关系,无法感知到输入向量维度与目标的关系。也就是当输入是完全没见过的向量,无法保证输出是合理的
为了改进,使得解码器输入没见过的向量,输出结果依然合理,在编码器输出引入一些噪声后 进行解码
但是 Auto encoder结构有一些问题,
自编码器的衡量是输出与目标图像的接近程度,也就是总体像素上的损失,而不是图像看起来是否像是一张合理的图像
相比来看,多一个像素没关系,但如果能把多的之后边缘补齐看起来就很好。----- 每个像素点的结果不是最重要的,最重要的是各个部分之间的相对位置等
但 同层神经元一般没有互相照应的能力,都是单独自己输出自己的值。若要解决,则需要更深的网络。
可视化,用auto encoder 学得的分布。
绿色为目标分布,蓝色为生成的分布
在不同的目标分布之间,依然有很多样本被生成出来
如何鉴别生成结果才是更好的? ---- 判别器
好的结果给高分
不好的结果给低分
卷积已经足够感知不同部分的相对位置
如何生成结果? 只使用判别器也是可以的,只要遍历样本空间中所有的样本,找到得分高的
但是解出如下方程 求得最好的x 是非常困难的
于是出现了生成模型,来求解判别器的argmax问题,也就是求得判别器认为好的x们
判别器的训练
将真实样本给高分,而偏离真实样本分布的其他样本给低分
训练过程大概会是这样
在GAN之前的生成方法:
对于生成器来说:希望自己能够无限逼近真实样本的分布
对于判别器来说:希望自己能够超高能力判别真实分布和伪造分布之间的差异
可视化由gan产生的伪造样本分布:
Conditional Generation by GAN
text to image
-
传统的监督训练问题
火车有很多, 如果输入火车,而目标是很多不同的火车(有正面,有侧面),网络会倾向于输出所有label的均值,结果可能是很不好的。 -
使用GAN来解决
Generator除了 接受一个条件词 train, 还接受一个噪声z,来控制各种不同风格。
而Discriminator 来判断 图像是否与条件词匹配,图像是否为真实图像,从而指导生成器
训练算法:
-
目前最常见的判别器架构
检测生成的x的真伪的同时检测条件c是否匹配
也有一些改进的判别器架构。取得了不错的效果
检测生成x的真伪情况,并检测与条件是否匹配,使用两个小网络 -
条件生成的小例子:
-
生成大图像的例子 stack GAN
图像生成图像
- 传统的监督策略
由于同样的输入对应了不同的输出,最终的结果会输出多个不同真实值的均值情况
- 利用GAN 引入了随机变量,能够使得不同的结果得到挖掘
- 对于图像的判别器 有些学者做了只检测若干区域,而不是整张图像
生成语音
- 语音加噪声, 输入噪声 让其输出伴有噪声的语音
- 判别器判别生成的语音、噪声 是否匹配
视频生成
- 预测接下来的一帧时间 视频会发生什么
Unsupervised Conditional Generation
风格迁移
没有x与y的一一对应,而是学习如何将x转换到另一个风格下。
-
生成器输入一个领域的样本, 生成结果交给判别器
-
判别器判断样本是否属于目标领域
-
但是容易发生生成器输出结果与输入结果差距过大,与原本图像无关的可能性。
为了解决这个问题,有如下策略:
1 用某个预训练模型将原图像与生成图像进行编码,使两者编码尽量接近。
2 在生成结果后面再接一个生成器将生成图转换到原图像
多个领域互转
- starGan
生成器输入 图像和目标领域信号
判别器:是否真实 and 哪个领域
- 自编码器 解决方案
问题:无法确定编码后的向量空间是相同的表达- 改进1
共用编码器输出层的一些向量空间 使得输出编码是相同的表达
- 改进1
- 改进2
增加一个编码的判别器,判别编码来自哪个domain
- 改进3
同时做两种风格的互转
生成再利用
Basic Theory behind GAN
- 假设数据x是一张图像,是一个高纬度向量
而数据实际上是以一个分部的形式存在的。 我们设为Pdata(x)
从分布中采样的结果看起来就是很好的图像,而偏离分部的采样看起来就很奇怪。
而且,data的分布其实只是在高纬度空间当中的非常小的一部分。
而Generation Model要做的,就是找到data的分布。
如何实现
- 极大似然估计
- 问题
- 高斯混合模型高斯数量?
- 样本的分布真的是高斯分布吗?
调整生成器 — 最小化KL散度
-
经过证明,发现调整Pg参数令在Pg中采样无限逼近Pdata中采样的 极大似然估计,其实就是最小化Pdata和Pg两个分布的KL散度
-
generator从一个普通分布,去映射到一个Pg, 使得Pg越接近Pdata越好
- 其实Pdata的分布一定不是一个高斯模型,而会是一个非常复杂的分布,
- 甚至是一个高维空间在低维度上的一个流形
- 接近的形式化就是最小化两个分布在某种散度Div上的值
-
我们并不知道两个分布Pg和Pdata,要如何实现最小化Div散度?
- 没有分布,用无限多的采样,来代替分布
- Pdata的采样为真实图像
- Pg的采样为 噪声出入给Generator的输出
-
如何实现计算两个分布的Div散度?
使用discriminator来实现- 固定G
- 构建一个目标函数V
- 进行最大化V
- 寻找最优的D
-
GAN的训练过程
- D的训练是,固定G,最大化Div散度
- G的训练是,固定D,最小化Div散度
调整判别器 — 最大化JS散度
- 寻找最优的判别器D
- 固定G
- 最大化V 即 最大化散度
- 如何找到最优的D令V最大?
- 经过计算发现, 最优的D其实就是在最大化两个分布的Js散度
- 经过计算发现, 最优的D其实就是在最大化两个分布的Js散度
f-divergence
- 衡量两个分布之间的差距
- KL散度和JS散度都是特例
可以选择让GAN优化各种不同的散度
- 不同的散度是解决mode colapse 和 mode dropping的方法
Tips for Improving GAN
JS散度的不妥之处
- 当两个分布之间没有重合的时候JS散度无法衡量两个分布之间的差距
- 当两个样本分布之间没有重合的时候,不论两个分布距离多远,JS散度的结果都是log2,
- 无法指导生成器生成更好的分布。
- 更形象的
- sigmoid在低分和高分的斜率太小,计算结果没有梯度,无法更新权重
- 改进:改为显性的激活
WGAN的策略
- 将优化目标改进 earth mover’s distance
- 可以看出 在样本分布没有重合的时候,earth distance 相比js 散度 仍然能够衡量分布之间的差距
- WGAN的算法
BGAN的策略
- 使用一个自编码器作为判别器D
- 认为如果能够重建的很好的图像为high quality,重建误差很大的图像为假图像
- 只需要用real image 去train判别器
- 一开始就能拥有能力很强的判别器,而不用迭代获得
Feature Extraction
- 希望输入的向量中某一个维度能改变生成结果某些内容。
- 传统的GAN方法,无法实现通过输入向量维度来控制输出。
即每一个维度对输出有一个明确的影响
info GAN
-
让生成结果能够用分类器预测输入的控制向量
-
第一维控制数字大小(info gan)
-
在Gan上无明显确切影响
-
第二维度控制字的方向、角度
-
第三维度改变字体的粗细程度
VAE-GAN
BiGAN
Triple GAN
Domain adversarial training
Evaluation
主观评价
- 陈列一大堆图,就说我们的生成结果是最好的
Inception Score
- 生成的目标的明确性
- 使用Inception Net
- 某一个生成的样本输入给inception net后,输出越具有明确类别越好
- 所有样本输入给inception net后结果进行平均,越平滑越好