Basic Idea of GAN
我们想要做到的事情就是,让机器生成东西,如图像、写诗。Gan要做的是训练出一个生成器,把不同的vector放入生成器就能生成不同的图像。generator实际上就是一个神经网络,它的输入就是一个vector,输出就是一个image,输入vector的每个dimension的数值代表产生图片的某个特征,假设第一个dimension代表头发长度,或者某个dimension的值代表头发的颜色。
Discriminator的输入是一张图片,它的输出是一个数值,数值越大,代表图片的质量越高。
举一个动漫人物生成的例子,首先要准备一个真实的动漫人物图像,最开始一个generator的参数是随机的,它也不知道如何产生图片,所以会产生一个杂乱无章的图片,discriminator要做的就是,识别出这个杂乱的图片是generator生成的,第二代generator要做的就是,想办法骗过第一代的discrimintor,第二代的discrimintor也会进化,要做的就是想办法识别出第二代生成的图片。二者互相进化对抗,就会产生越来越好的图片。
算法流程
step1: 固定住generator,去更新discriminator的参数。这时候把一堆随机的向量丢给G,因为最开始它的图片是随机的,所以它产生的图片并不会特别好,接下来从真实的图片中采样出一组图片。现在有两组图片,一组是G生成的,另一组是database中真实存在的。接下来需要去训练D,也就是调整D的参数。让D给真实图片高分,给G生成的图片低分。具体来说,把真实图片丢给D,D输出一个接近1的值,把G生成的图片丢给D,D输出一个接近0的数值。
step2 固定住D,去更新G的参数。先把一个vector丢给G,G会输出一个图片,把这个图片交给D,让D去打分。 实际上去做的时候,是把G和D合起来处理,把他们俩当成一个巨大的网络,可以看做这个大网络的输入是一个vector,输出是一个数值。
Can Generator learn by itself
Generator 是可以自己学习的,G可以看做是一个神经网络,是能够做到输入一个vector,让它输出一张图片的。在传统的监督学习里,需要给网络提供一对数据,然后训练下去,就能得到结果。最后让得到的图片, 和真实图片,越接近越好。但是问题是怎么产生这样的数字图片呢,肯定不能随机产生,因为随机产生的话,G的训练会很困难,因为图中的两个1是很像的,如果输入的向量很不一样的话,就很难训练出这样一个网络--输入很不一样的东西,却输出很相似的东西。所以在产生一对数据时,要让两个图片有共同的特征,对应的向量也要相似。比如,向量第一维可能与数字的值有关,第二维可能与倾斜度有关,等等。
下面提到一种Auto-encoder技术,自编码器做的事情就是,给一张图片,编码器输出一个code,但是自编码器不能自己训练,需要加一个解码器,解码器吃一个code,得到一个图片。在训练的时候,希望解码器得到的图片和原始输入的图片越接近越好。训练好之后,NN Decoder就是我们需要的,随便给它一个code,他就能输出一个图片。
但是自编码器会有什么问题?因为我们的训练集是有限的,训练好的网络可能会不够聪明,比如,看到a可能产生向左的数字,看到b可能产生向右的数字,但是看到0.5a+0.5b产生的图片可能根本就不是一个数字。
所以VAE解决了这个问题,在生成code的时候,加入了一些噪声。这样训练好的网络,它在生成图片的时候就能做到,在看到向量a时,产生一个数字,在看到向量b时,也产生一个数字,看到向量a加一个噪声也会产生一个数字。
但是这种auto-encoder方法缺少了什么?这种生成器的目标是希望output和target越像越好,但什么是越像越好?通常计算的是,这两张图片pixel by pixel之间的差距,把这两张图片表示成两个高维的vector,接下来去算两个vector的相似度,比如欧氏距离越小越好。但是这种相似有个问题。如下图,前两个图与原图只有一个像素的差异,机器认为它们很好,但实际上,从人的角度出发,我们更偏向下面的两幅图,因为它们可以理解成手写数字出现了连笔,而不是像图二那样,中间有个洞,不符合手写数字的特点。
上面提到的问题是,auto-encoder模型没有考虑component和component之间的关系,就是没有从大局上去生成,根据经验,其实也能产生更好的结果,但是或许需要更深的网络。
Can Discriminator generate
上面说过,让G去自己产生图片的话,它是一个一个component独立生成的,他不会考虑到component之间的关系,但对D来说,它就很容易去考虑component和component之间的关系,因为对D来说,它的输入是一张图片,它可以用一个CNN卷积核去扫描图片。
回到问题,要想让D去自己生成图片,可以根据下面那个式子,让D去穷举所有的的图片,最高分的图片,就是想要的图片。当然这很困难,D不擅长生成,它只擅长批评。而且前提是,如何训练D,让D有打分的能力。
现在先去看看它怎样训练。因为只有D的话,没有G给他提供坏图片,它手上只有好的图片,这个时候,D只看到正面的例子,只用正面例子去训练它,它会给所有的图片都打高分。
训练D的方法是。先随机给出一些噪音作为假数据,在每次训练中,让D学会初步的打分,然后我们假设有办法让D去生成,例如穷举。D会根据初步的打分生成一些稍好的图片,然后把这组稍好的图片作为反例交给D,让D去增强打分的能力。反复训练下去,也能生成。
Generator vs Discriminator
Generator + Discriminator 就解决了他们两个的局限性,生成器虽然考虑不到component之间的关系,但是判别器可以,判别器虽然不容易生成图片,但是生成器可以。