生成对抗网络
生成对抗网络(GANs)
顾名思义,生成对抗网络由两部分组成,一是生成模型,就像之前介绍的自动编码器的解码部分。二是对抗模型:严格来说是一个判断真假图片的判别器。
简单来说,生成对抗网络就是希望两个网络相互竞争,通过生成网络生成假的数据,对抗网络判别真伪,最后希望生成网络生成的数据能够以假乱真。
生成模型
此处生成模型不再是将图片输入编码器再通过解编码生成假图片,而是随机初始化一个隐含向量,生成图片,具体步骤如下:首先给出一个简单的高维的正态分布的噪声向量,然后这个时候我们可以通过仿射变换,也就是 xw+b 将其映射到一个更高的维度,然后将他重新排列成一个矩形,这样看着更像一张图片,接着进行一些卷积、转置卷积、池化、激活函数等进行处理,最后得到了一个与我们输入图片大小一模一样的噪音矩阵,这就是我们所说的假的图片。
这个时候我们如何去训练这个生成器呢?这就需要通过对抗学习,增大判别器判别这个结果为真的概率,通过这个步骤不断调整生成器的参数,希望生成的图片越来越像真的,而在这一步中我们不会更新判别器的参数,因为如果判别器不断被优化,可能生成器无论生成什么样的图片都无法骗过判别器。
对抗模型
对抗模型简单来说是一个真假图片的判别器,所以其实就是一个二分类问题。对于假的图片我们期望它输出为0,真的图片我希望它输出为1,这个输出与原图片label没关系,不管原图片有多少总分类,对抗模型都只是一个判断图片为真或为假 的二分类问题。
在训练时,我们先对对抗模型进行训练,希望其能正确区分真的或假的图片。然后再训练生成模型,希望其生成的图片能够骗过对抗模型。
对于此二分类问题,可以用我们前面讲过的很多方法去处理,比如 logistic 回归,深层网络,卷积神经网络,循环神经网络都可以。
生成对抗网络的数学推导
引入KL divergence:
$$
DKL(P\Vert Q)=\int_{-\infty}^{\infty}p(x)\log\frac{p(x)}{q(x)}dx
$$
$$
DKL(P\Vert Q)=\sum_{-\infty}^{\infty}p(i)\log\frac{p(i)}{q(i)}
$$
其可用于衡量两个分布的差异程度,KL divergence越小,两种概率分布越接近。
生成对抗网络想要将一个随机高斯噪声z通过生成网络G得到一个和真实数据分布$p_{data}(x)$差不多的分布$p_G(x;\theta)$,其中$\theta$为网络参数。
从真实数据分布$p_{data}(x)$中采样m个点${x^1,x^2,…,x^m}$,那么生成数据中与这m个点相同的似然为:
$$
L=\prod_{i=1}^mp_G(x^i;\theta)
$$
那么我们所需网络参数$ \theta $可由最大化以上似然函数求得:
$$
\begin{aligned}
\theta^&=\arg_\theta max\prod p_G(x^i;\theta)\\
\log \theta^&=\arg_\theta max\log\prod p_G(x^i;\theta)\\
&=\arg_\theta max \sum \log(p_G(x^i;\theta))\\
&\approx\arg_\theta maxE_{x\sim p_{data}}\log(p_G(x;\theta))\\
&\Leftrightarrow \arg_\theta max \int_xp_{data}(x)\log\frac{p_{G}(x;\theta)}{p_{data}(x)}\\
&=\arg_\theta\min DKL(p_{data}(x)\Vert p_G(x;\theta))
\end{aligned}
$$
但是我们如何求得$p_G(x;\theta)$呢?我们只知道生成器的先验分布,这里很难通过极大化似然估计求得$\theta$
有没有办法来取代极大似然估计呢?答案是有的,首先定义如下函数:
$$
V(G,D)=E_{x\sim P_{data}}[\log D(X)]+E_{x\sim P_{G}}[\log (1-D(X))]
$$
其中D为对抗模型参数,先给出我们求G的公式:
$$
G^*=\arg \min_G\max_DV(G,D)
$$
怎么得到这个式子的呢?请往下看:
$$
\begin{aligned}
V(G,D)&=E_{x\sim P_{data}}[\log D(X)]+E_{x\sim P_{G}}[\log (1-D(X))]\\
&=\int_x P_{data}(x)\log D(x)dx+\int_x p_G(x)\log(1-D(x))dx\\
&=\int_x[P_{data}(x)\log D(x)]+[p_G(x)\log(1-D(x))]dx
\end{aligned}
$$
首先我们固定G,求一个最优的D使得上式最大,看看其代表什么含义吧:
$$
\begin{aligned}
f(D)&=[P_{data}(x)\log D(x)]+[p_G(x)\log(1-D(x))]\\
&=a\log(D)+b\log(1-D)\\
\frac{df(D)}{dD}&=a\times\frac{1}{D}-b\times \frac{1}{1-D}=0\\
D^*&=\frac{P_{data}(x)}{P_{data}(x)+P_G(x)}
\end{aligned}
$$
那么将$D^*$带入原式:
$$
\begin{aligned}
\max V(G,D)&=V(G,D^*)\\
&=\int_x P_{data}(x)\log\frac{P_{data}(x)}{P_{data}(x)+P_G(x)} dx+\int_x p_G(x)\log\frac{P_{G}(x)}{P_{data}(x)+P_G(x)}dx\\
&=\int_x P_{data}(x)\log\frac{\frac{1}{2}P_{data}(x)}{\frac{P_{data}(x)+P_G(x)}{2}} dx+\int_x p_G(x)\log\frac{\frac{1}{2}P_{G}(x)}{\frac{P_{data}(x)+P_G(x)}{2}}dx\\
&=-2\log2+2JSD(P_{data}(x)\Vert P_G(x))
\end{aligned}
$$
其中:
$$
JSD(P\Vert Q)=\frac{1}{2}DKL(P\Vert M)+\frac{1}{2}DKL(Q\Vert M),M=\frac{1}{2}(P+Q)
$$
由$$D^* $$所获的$$maxV(G,D^)$$包含两个KL divergence,那我们所求$$G^$$就得使其最小:
$$
G^*=\arg \min_G\max_DV(G,D)
$$
生成对抗网络的代码实现
下面我们来进行一下代码实现:
简单的全连接神经网络作为生成和对抗模型:
import torch |
上述为该网络经过训练生成的图片,可以看到已经接近手写数字,但效果还不是很好。都说CNN是处理图片最好的网络,那么我们能不能使用CNN作为生成和对抗模型呢?答案当然是可以的,这样的网络被称为 DC GANs,那效果又如何呢?
import torch |
可以看到,生成图像十分清晰,比全连接神经网络效果好很多
Least Squares GAN
Least Squares GAN 比最原始的 GANs 的 loss 更加稳定,通过名字我们也能够看出这种 GAN 是通过最小平方误差来进行估计,而不是通过二分类的损失函数,下面我们看看 loss 的计算公式
$$\ell_G = \frac{1}{2}\mathbb{E}_{z \sim p(z)}\left[\left(D(G(z))-1\right)^2\right]$$
$$
\ell_D = \frac{1}{2}\mathbb{E}{x \sim p\text{data}}\left[\left(D(x)-1\right)^2\right] + \frac{1}{2}\mathbb{E}_{z \sim p(z)}\left[ \left(D(G(z))\right)^2\right]
$$
def ls_discriminator_loss(scores_real, scores_fake): |
清晰度更高,效果有所提升。