1. Algorithm
- Step 1: Fix generator G, and update discriminator D
用deblurGAN中定义的变量来说明
input是real_A(blur image), G网络生成的output是fake_B, 而target是real_B, 那在这一步, 就是已经获得了G网络得到的fake_B, 去计算loss_D, 所以计算D网络的loss就是这样一个函数, D网络实际就是一个二分类网络, 它的理想态就是对于所有的真样本都输出1, 假样本都输出0
loss_D = loss_D(netD, real_A, fake_B, real_B)
我们看一下原始GAN是如何定义这个loss_D
两个部分, 一个部分是logD(x), x就是real_B, 就是real_B进入D网络, 希望结果越大越好, 越接近1; 另一个部分是log(1-D(G(z))), z就是real_A, G(z)就是G网络生成的fake_B, 就是fake_B进入D网络, 希望结果越小越好, 越接近0. 公式里面的E应该是所有相关样本的结果送入网络得到输出后进行Σ的意思, 而x~pdata(x)就是说x是真实数据(real_B), z~pz(z)是说z是网络的输入数据(real_A)
训练D的时候, 没有G网络的事儿, G(z)在这里相当于已经得到的假样本fake_B, 实际上就是两张图参与运算loss_D, real_B和fake_B, real_A已经用不上了, 因为G是一个固定的网络, 参数不用调, 反向的过程只优化D网络里的参数
- Step 2: Fix discriminator D, and update generator G
loss function还是那个loss function, 但是因为这个时候D是fix住的, 我们的目标就是通过调整G网络的参数, 让D网络来给fake_B更高的output分数, 通俗讲, 就是要骗过D网络, 这个时候没有真样本什么事儿了, 输入的都是real_A, 所以loss function的前面一项就没有用了.
反向的时候, D网络的参数被fix住, 根据loss来调整G网络的参数, 这个时候real_A就是有用的, 因为要计算梯度, 需要输入的x
- Algorithm pseudo-code
这是最原始的GAN的pseudo-code, 实际上在learning D和learning G这两个过程, 都用的是gradient ascent, 所谓gradient ascent就是梯度上升, 就是梯度下降反向的过程, gradient descent是w-learning_rate*∇w, 那gradient ascetn就是反过来, 每次朝梯度方向走一点, w+learning_rate*∇w
注意learning G的时候loss function改成了log(D(G(z))), 这样, 就使得learning D和G的过程都是gradient ascent
2. Theory base of GAN
- Structured Learning
- Why Structured Learning Challenging
所谓one-shot/zeros-shot learning, 指的是要NN产生的output在sample中极少, 或者是根本就没有, 也就是说要让NN"创造"出它只见过一次(training data)或者是根本没见过(test data)的东西
这里说的overall situation是讲的大局观, 就是说在GAN的过程中生成的component不重要(比如图像的pixel), 重要的是这些component之间的关系, 就是在产生这些component的时候机器要有大局观, 知道component的组合会有怎么样的意义
GAN实际上是传统structured learning方法中Bottom up和Top down方法的结合
3. Can Generator learn by itself?
怎么得到靠谱的code(与图像的特征相关)? -- Auto-encoder
像这种左偏的1和右偏的1 code相加, 如何保证它输出的是1而不是噪声呢? -- VAE
- What do we miss
如果我们可以用auto-encoder产生vector, 单独训练Generator就可以生成image, 那为什么我们还需要Discriminator?
因为Generator不得不去犯一些错误, 关键就是你的loss function引导它去犯什么样的错误, 如果就是l1/l2 distance这样的loss function, 那它就会倾向去犯上面两个错误, 但是从人的观点来看, 下面两张更可以接受, 虽然pixel level上的distance更远
从教育的观点上理解, 教育孩子, 简单的loss就是分数, 你希望他考的越高越好, 越高挨的打就越少(penalty), 但是每科100分这种target肯定是很难达到的, 为了减少penalty, 他可能会作弊, 可能会修改分数, 因为在你的loss function里, 这些行为不会产生penalty, 只有分数低会, 就像图上的Generator一样, 你如果只关心pixel level的distance, 有可能会在某些地方产生偏差, 分数倒是不差, 但是与你想要的结果会有偏差, 所以Generator我们需要的是更高级target和loss function, 就是它是不是我们人眼能够接受的真实结果, 不是pixel level的data distance, 教育孩子也是一样, 我们的高级target是他成长为一个品格高尚又有出众能力的人才, 而不简单是每次都可以获得高分数
这页slide说明我们其实不关心你生成的component, 就是你在错误位置点个点其实不要紧, 关键是这个点是不是影响了这个图像的意义, 也就是影响了整体pixels之间的relationship, 比如机器在错误的地方点了个点你觉得不ok, 但如果机器把深红色部分也都点上了点, 你就会觉得ok, 所以what do we miss, 如果只有Generator, 我们缺的就是理解component之间关系的手段
如果只有Generator, 那训练完的结果长这样, 就是没有考虑到target(绿色点)之间有更高级的relationship, 或者说它们的分布遵循着更高级的规律
4. Can Discriminator generate?
用discriminator产生图像的方法, 就是穷举所有图像的可能性, 然后一个一个去评价, 找一个最高分数的图像, 这个就是产生的object, 这就是没有Generator, 只有Discriminator的时候产生图像的办法. 但是要怎么去训练这个Discriminator?
Discriminator就是一个二分类网络, 那只要给足正负样本就可以了, 但问题是只有Discriminator的话, 我们的负样本从哪里来, 就是你怎么告诉它什么是不好的样本?
好的负样本是关键, 正样本当然都是真实的, 但负样本假的程度是有差异的, 只有给它足以以假乱真的负样本它才能够成长为一个合格的Discriminator
Discriminator训练是一个迭代的过程, 就是让它自己寻找自己的弱点, 每一次自己生成一堆fake样本, 怎么用Discriminator来做Generate呢, 就是遍历找Discriminator给的分数最大的样本, 然后再以Generate的这些fake样本作为Negative样本送入下一轮Discriminator训练的迭代
上面讲的用Discirminator来Generate的方式, 和训练Discriminator的方法, 实际就是general的Graphical Model的training, Bayesian Network和Discriminator的关系
用GAN比单独用D来generate的好处, 就是用G来代替求argmaxD(x)的问题, 因为维度高和非线性问题, argmaxD(x)可能根本就没法解, 而G的训练就是以让D判断fake图像为true为目的, 所以通过优化G来获得x^hat
VAE比较稳, 但是很难产生好的结果.