GANs
生成对抗网络(Generative Adversarial Networks, GANs)是一种用于捕获训练数据的**分布(distribution)**的神经网络。通过学习到的分布,可以创造新的数据。GAN由两个部分组成:
生成器(generator):用G(z)G(z)G(z)表示,输入是(一般为正态分布采样的)随机噪声zzz,输出是和训练数据等大的“fake”数据;判别器(discriminator):用D(x)D(x)D(x)表示,用来判断输入数据xxx是否为真正的训练数据,输出是一个[0,1][0,1][0,1]区间的标量,输出值越大表示DDD判定xxx更可能是真实训练数据,越小则更可能是假的数据。
生成器和判别器之间是一个零和博弈的过程:生成器的效果越好,则判别器的正确率越低,反之亦然。在训练过程中,生成器的目的是“让判别器判断错误”,因此会生成越来越接近真实训练数据的假数据,这个过程也是学习训练数据分布的过程;判别器的目的则是“更好地区分真实数据和假数据”,因此学习过程会提高它的判别能力。
以上是一个感性的认知,在神经网络学习的框架下,需要定义一个具体的损失函数(loss),来对生成器和判别器的参数进行梯度更新。定义损失函数:
LGAN=Ex[logD(x)]+Ez[log(1−D(G(z)))],L_{GAN}=\mathbb{E}_{x}{[logD(x)]}+\mathbb{E}_{z}{[log(1-D(G(z)))]}, LGAN=Ex[logD(x)]+Ez[log(1−D(G(z)))],
式中的x∼pdata(x)x \sim p_{data}(x)x∼pdata(x)取自训练数据,z∼pnoise(z)z\sim p_{noise}(z)z∼pnoise(z)为生成器GGG的随机噪声(一般满足正态分布)输入,E\mathbb{E}E表示期望。
对于判别器DDD,我们的目的是:真实数据xxx,D(x)D(x)D(x)尽量更大;假数据G(z)G(z)G(z),D(x)D(x)D(x)尽量更小,亦即1−D(x)1-D(x)1−D(x)尽量更大。因此判别器的训练过程的损失函数为−LGAN-L_{GAN}−LGAN。
对于生成器GGG,我们的目的是:真实数据xxx,与GGG无关,可以当做一个常数;假数据G(z)G(z)G(z),希望判别器“认为它是真实数据”,也就是希望1−D(x)1-D(x)1−D(x)尽量更小。因此生成器的训练过程的损失函数为LGANL_{GAN}LGAN。
综上,GAN的训练本质上是一种极大极小博弈(minimax game):
minGmaxDLGAN\min_{G}\max_{D} L_{GAN} GminDmaxLGAN
理论上,训练最终会收敛于pnoise=pdatap_{noise}=p_{data}pnoise=pdata,也就是生成器学习的概率分布与训练数据的一致,而判别器的输出等价于随机判定真假。但实际上GAN的训练过程很不稳定。
一个例子
使用CelebA人脸数据集训练一个DCGAN。所谓DCGAN,就是生成器和判别器都是卷积神经网络的GAN。训练后的生成器可以用随机噪声生成和训练集相似的人脸图像。
训练使用二进制交叉熵损失函数(BCELoss):
BCELoss(x,y)=−1n∑i[yilogxi+(1−yi)log(1−xi)],BCELoss(x,y)=-\frac{1}{n}\sum_{i}{[y_ilogx_i+(1-y_i)log(1-x_i)]}, BCELoss(x,y)=−n1i∑[yilogxi+(1−yi)log(1−xi)],
这和之前讲到的LGANL_{GAN}LGAN非常相似,通过合理地选择标签yyy就可以等价的表示LGANL_{GAN}LGAN。训练过程的一个iter的过程如下(关键步骤):
输入数据x1x_1x1从训练图像数据中得到,为真实数据,取标签y=1y=1y=1,前向传播(forward)得到D(x1)D(x_1)D(x1),得到损失L1=BCELoss(D(x1),y=1)=−1n∑ilogDi(x1)L_1=BCELoss(D(x_1),y=1)=-\frac{1}{n}\sum_ilogD_i(x_1)L1=BCELoss(D(x1),y=1)=−n1∑ilogDi(x1);输入数据x2=G(z1)x_2=G(z_1)x2=G(z1),为假数据,取标签y=0y=0y=0,前向传播得到D(x2)D(x_2)D(x2),得到损失L2=−1n∑ilog(1−Di(x2))L_2=-\frac{1}{n}\sum_{i}log(1-D_i(x_2))L2=−n1∑ilog(1−Di(x2)); (上面的DiD_iDi为单个图像的输出,DDD为一个batch的输出。)从1和2我们得到了判别器DDD的损失LD=L1+L2=−LGANL_{D}=L_1+L_2=-L_{GAN}LD=L1+L2=−LGAN,对判别器进行参数更新;更新后的判别器重新对x2x_2x2进行判定,得到输出D′(x2)D'(x_2)D′(x2),取标签y=1y=1y=1,得到损失LG=−1n∑ilogDi′(x2)L_G=-\frac{1}{n}\sum_ilogD_i'(x_2)LG=−n1∑ilogDi′(x2),前面我们说了生成器的目的是最小化LGANL_{GAN}LGAN,而logD(x)logD(x)logD(x)这一项为常数项,因此生成器的目的等价于最小化log(1−D(G(z)))log(1-D(G(z)))log(1−D(G(z))),又等价于最小化−logD(G(z))-logD(G(z))−logD(G(z)),这正好对应LGL_GLG;从4我们得到了生成器GGG的损失LGL_GLG,对生成器进行参数更新。
训练后的模型的生成器的输出和原始图片数据的对比:
代码在这里。