生成对抗网络原理解析与损失函数推导 | 刘广睿的思维实验室
0%

生成对抗网络原理解析与损失函数推导

本文以最基本的概念讲解生成对抗网络的设计原理,基于信息论与概率论分析生成对抗网络损失函数的推导过程。文章有助于理解不限于生成对抗网络的其它深度学习损失函数推演思路,致力于使读者可以举一反三构造符合特定环境的生成对抗网络。

1 机器学习模型

机器学习模型可以实现如分类、聚类、回归、生成等许多功能,而要理解生成对抗网络(GAN)我们要先明白分类器和生成器的功能。

分类器(Classifier) 分类器模型可以通过学习一些样本的类别信息,然后便能对输入的未知类别样本进行分类。比如让机器看一些不同类别的动物图片并告诉它图片对应的动物类别,然后机器便可自己辨别新的图片是哪个类别,这就是分类器。
生成器(Generatior) 生成器模型可以通过学习一些样本,然后便能生成类似的样本。比如让机器看一些动物图片,然后机器便可自己生成动物图片,这就是生成器。

2 生成对抗网络

2.1 古典生成器模型缺陷

GAN是一种生成器,在它出现之前已经有了很多种类的生成器模型,比如玻尔兹曼机、变分自编码器等,这些模型多使用生成数据和真实数据之间的MSE值(mean square error)来判断模型的好坏,其判断依据可以简单理解为生成数据与真实数据之间的距离,距离越小则认为效果越好。但在使用时人们逐渐发现使用这种判断方式的生成器效果并不理想,尤其对于手写数字或小型图标等简单图像,MSE并不能有效反映生成图片的优劣。在图1中,我们认为左侧的数字“7”是好的生成图片,而右侧是差的生成图片,但两者MSE值相等。

图1:左侧的数字“7”是好的生成图片,右侧是差的生成图片。

2.2 生成对抗网络原理

2014年Ian Goodfellow提出了生成对抗网络模型,他从零和博弈中受到启发,令生成器(Generatior)与判别器(Discriminator)之间持续对抗,使两者能力不断增强。其中判别器是一种特殊的分类器,它是只有“是”或“否”两种输出的二元分类器。下面我们通过定性描述来直观理解一下GAN的构造。

如图2所示,GAN由三部分组成:生成判别对抗。生成和判别是两个独立的模块,分别由生成器与判别器实现。而对抗指的是生成器与判别器的交替训练过程。
图2:GAN基本结构

生成模块:生成模块由生成器实现。负责依据随机向量产生样本,如图片、文字等。
判别模块:判别模块由判别器实现。负责判断接收到的样本是真实样本还是生成器生成的样本。
对抗模块:对抗模块构建生成模块与判别模块的关联,实现两者交替训练。

训练过程分为两步:

  • Step1 先让生成器产生一些假样本,和收集到的真实样本一起输入判别器,让判别器学习正确区分两者。
  • Step2 当判别器能够熟练的判断现有数据后,再让生成器以生成能够欺骗判别器的假样本为目标,不断生成更好的假样本。

重复进行Step1Step2 可使生成器与判别器相互促进,生成器的目的是让产生的样本逼近真实类别样本以假乱真,判别器的目的是将真实样本与生成器生成的样本加以区分。所以生成器产生的样本会越来越真实,而判别器的判别能力也会越来越强,最终达到纳什均衡。当判别器对任何样本的预测概率都接近0.5,即无法分辨样本是真实的还是生成器生成的,就停止训练。GAN的最终目标是产生一个足够好的生成器,其可以通过输入的随机向量,生成能够以假乱真的样本。

3 信息论

3.1 信息量

生成对抗网络要准确计算并生成以假乱真的样本,就需要用损失函数定量的分析生成器与判别器的性能优劣。机器学习的损失经常使用交叉熵来定义,生成对抗网络也同样使用交叉熵来定义损失。想理解生成对抗网络损失函数的本质,要从最基本的信息量讲起。信息量顾名思义即信息的数量,其大小通过事件发生概率的负对数衡量。为了便于理解,我们通过以下例子解释信息量的定义。假设我们听到了两件事,分别如下:

  • 事件A 巴西队进入了2022年世界杯决赛。
  • 事件B 中国队进入了2022年世界杯决赛。

凭直觉来说,很显然事件B的信息量比事件A 要大。究其原因,是因为事件A发生的概率很大,而事件B发生的概率很小。当越不可能的事情发生了,我们获取到的信息量就越大。越可能发生的事情发生了,我们获取到的信息量就越小。由此可见,信息量应该和事件发生的概率有关。

进一步的,必然事件是必然发生的,所以没有信息量。几乎不可能发生的事情一旦发生,则具有近乎无穷大的信息量。举例来说,我永远不会死这句话信息量就近乎无穷,而我是我妈生的这句话信息量就很低甚至为0。

通过以上的分析,可以得到信息量与概率的关系如图3所示,设$ X $是一个离散型随机变量,其取值集合为$ \chi $,概率分布函数$ p(x)=P_r(X=x),x \in \chi $,则定义事件$X = x_0$的信息量为:

\begin{equation}
I(x_0)=-log(p(x_0)) \label{amount_of_information}
\end{equation}

其中$ p(x_0) $的取值范围是$ [0,1] $。

图3:信息量与概率的关系

3.2 熵

熵是一种用来描述事物内在混乱程度的度量,混乱程度越大则熵越大,混乱程度越小则熵越小。在信息论中熵可以表示一个事件的自信息量,即事件包含多少信息。比如对于一个必然事件,它的所有状态都是确定不变的,不会产生任何混乱或变化,那么它的熵就是最小值0。一般的,对于某个事件,其有$ n $种可能性,每一种可能性都有一个概率$ p(x_i) $,我们可以通过公式\eqref{amount_of_information}计算出每一种可能性的信息量,那么如何计算熵呢?下面我们来看一个更加典型的例子来进一步理解。

假设你拿出了你的电脑,按下开关,会有三种可能性,下表列出了每一种可能的概率与其对应的信息量。

序号事件概率信息量
A电脑正常开机0.7$ -log(p(A))=0.36 $
B电脑无法开机0.2$ -log(p(B))=1.61 $
C电脑爆炸了0.1$ -log(p(C))=2.30 $

注:文中的对数为均为自然对数

我们有了所有可能性的信息量,而熵被定义为所有信息量的期望,以描述该事件的自信息量,即:

\begin{equation}
H(X)=- \sum_{i=1}^np(x_i)log(p(x_i)) \label{entropy}
\end{equation}

其中$ n $代表所有的$ n $种可能性,所以上面问题的结果就是:

\begin{align}
\nonumber
H(X) &= - \left [ p(A)log(p(A))+p(B)log(p(B))+p( C)log(p( C)) \right ]\\ \nonumber
&= 0.7 \times 0.36 + 0.2 \times 1.61 +0.1 \times 2.30\\ \nonumber
&= 0.804
\end{align}

值得一提的是,如投掷硬币这类比较特殊的问题,它只有两种可能,正面朝上或背面朝上,我们称之为0-1分布问题(二项分布的特例)。对于这类问题,熵的计算方法可以简化为如下算式:

\begin{align}
\nonumber
H(X) &=- \sum_{i=1}^np(x_i)log(p(x_i)) \\
&= -p(x)log(p(x))-(1-p(x))log(1-p(x))\\ \label{binomial_distribution_entropy}
\end{align}

3.3 相对熵(KL散度)

相对熵又称KL散度,如果我们对于同一个随机变量x有两个独立的概率分布$ P(x) $和$ Q(x) $,我们可以使用KL散度来衡量这两个分布的差异。具体来说,相对熵就是用$ P $来描述目标问题相比用$ Q $来描述,得到的信息增量。

在机器学习中,$ P $往往用来表示样本的真实分布,比如$ [1,0,0] $表示当前样本属于第一类。$ Q $用来表示模型所预测的分布,比如$ [0.7,0.2,0.1]。 $
直观的理解就是如果我们用$ P $分布来描述样本,那么就非常完美。而用$ Q $分布来描述样本,虽然可以大致描述,但是不是那么的完美,信息量不足,需要额外的一些“信息增量”才能达到和$ P $一样完美的描述。如果我们通过对模型的反复训练使$ Q $也能完美的描述样本,那么就不再需要额外的“信息增量”,$ Q $等价于$ P $。可以看出,减小$ P $与$ Q $之间的差距,即降低相对熵就是机器学习在训练模型时要达到的目标。

KL散度的公式推导基于使用不同的编码描述目标样本所产生的熵差,这里不详细推导,直接给出KL散度的计算公式:

\begin{equation}
D_{KL}(p||q)=\sum_{i=1}^np(x_i)log(\frac{p(x_i)}{q(x_i)}) \label{kullback_leibler_divergence}
\end{equation}

其中$ n $为事件的所有可能性。$ D_{KL} $的值越小,表示$ q $分布与$ p $分布越接近。

3.4 交叉熵

对公式\eqref{kullback_leibler_divergence}变形可以得到:

\begin{align}
\nonumber
D_{KL}(p||q) &= \sum_{i=1}^np(x_i)log(p(x_i)) - \sum_{i=1}^np(x_i)log(q(x_i))\\ \nonumber
&= -H(p(x)) + \left [ - \sum_{i=1}^np(x_i)log(q(x_i)) \right ]
\end{align}

等式的前一部分恰好是$ p $的熵,而将等式的后一部分定义为交叉熵:

\begin{equation}
H(p|q)=- \sum_{i=1}^np(x_i)log(q(x_i)) \label{cross_entropy}
\end{equation}

在机器学习中,为了评估样本真实类别(label)和模型预测类别(predicts)之间的差距,我们使用KL散度来判定模型的优劣,即$ D_{KL}(y||\hat y) $,由于KL散度中的前一部分$ −H(y) $是样本类别在真实世界中的熵,其固定不变,故在优化过程中,只需要关注交叉熵就可以了。所以一般在机器学习中将模型的损失(loss)直接定义为交叉熵。这里的损失指的就是用模型预测分布描述样本相较于样本真实分布损失的信息量。优化损失函数(即交叉熵)使其最小化,便可令模型预测分布与样本真实分布尽可能的接近,使模型的预测能力增强。

特殊的,当随机分布$ P $和$ Q $是都二项分布时,即$ P $和$ Q $只有两个状态$ 0 $或$ 1 $,那么它们的差异可以用二进制交叉熵表示。令$ p $为$ P $的状态$ 1 $的概率,则$ (1-p) $是$ P $的状态$ 0 $的概率,同理,令$ q $为$ Q $的状态$ 1 $的概率,$ (1-q) $为$ Q $的状态$ 0 $的概率,则$ P $与$ Q $之间交叉熵为:

\begin{equation}
H(p|q)=-(plog(q)+(1-p)log(1-q)) \label{binomial_cross_entropy}
\end{equation}

4 损失函数

4.1 分类模型损失函数

这里我们只讨论单分类问题,即每一个样本只能属于一个类别,比如一张图片只能是猫或者是狗,不能既有猫又有狗。那么此类问题的机器学习模型计算某一个样本的损失一般的方法是:

\begin{equation}
loss = - \sum_{i=1}^n y_ilog(\hat{y_i}) \label{loss}
\end{equation}

其中$ n $代表总类别数量,$ y_i $为标签值(Label),$ \hat{y_i} $为预测值(Pred)。举例说明样本损失的计算方法,比如有以下样本:
图4:猴子图片样本
对应的标签值和预测值如下表:

*猴子老鼠
Label010
Pred0.30.60.1

那么模型对该样本损失为:

\begin{align}
\nonumber
loss &= -(0 \times log(0.3) + 1 \times log(0.6) + 0 \times log(0.1))\\ \nonumber
&= -log(0.6)
\end{align}

而对应一批样本(一个batch),则将其loss定义为其中所有样本loss的平均值(期望):
\begin{equation}
batch\ loss = -\frac{1}{m} \sum_{j=1}^m \sum_{i=1}^n y_ilog(\hat{y_i}) \label{batch_loss}
\end{equation}
其中$ m $为当前batch中的样本数。

4.2 GAN损失函数

2014由Ian Goodfellow首次提出的GAN损失函数为:
\begin{equation}
\min_G \max_D V(D,G) = E_{x\sim p_{data}(x)} \left [ logD(x) \right ] + E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \label{GAN_loss}
\end{equation}

看到这一长串公式可能让人很难理解,下面我们将详细讲解其推导过程。

4.2.1 判别器损失

在GAN中,判别器(Discriminator)的优化目标是缩小判别器输出$ D(x) $的概率分布$ D $与样本真实标签概Label率分布$ L $的差异。其中$ L $与$ D $均为二项分布,$ L $概率分布只有两个取值100%或0%,即$ 1 $和$ 0 $;而$ D $概率分布表示判别器认为样本为真的概率,它的取值为100% ~ 0%,即$ [0,1] $。

那么,如果一个样本(一幅图片)$ x $是真实的(real),$ p $则为$ 1 $,$ q $为$ D(x_r) $,其交叉熵为:

\begin{align}
\nonumber
H(L|D_r) &= -(plog(q)+(1-p)log(1-q))\\ \nonumber
&= -(1 \times logD(x_r)+(1-1) \times log(1-D(x_r))\\
&= -logD(x_r) \label{discriminator_real_entropy}
\end{align}

如果一个样本是生成器生成的,即为假的(fake),$ p $则为$ 0 $,$ q $为$ D(x_f) $,其交叉熵为:

\begin{align}
\nonumber
H(L|D_f) &= -(plog(q)+(1-p)log(1-q))\\ \nonumber
&= -(0 \times logD(x_f)+(1-0) \times log(1-D(x_f))\\
&= -log(1-D(x_f)) \label{discriminator_fake_entropy}
\end{align}

于是,对于一个同时含有真实样本(real)与生成器生成样本(fake)的样本集,其交叉熵的平均值(期望)为:

\begin{equation}
H(L|D) = -\frac{1}{M}(\sum_{x_r}^M log(D(x_r)) + \sum_{x_f}^M log(1-D(x_f))) \label{discriminator_entropy}
\end{equation}

如上所述,判别器的优化目标是缩小$ D $与$ L $概率分布的差异,即最小化交叉熵。所以可以将判别器损失定义为

\begin{equation}
Loss_D = H(L|D) = -(\frac{1}{M}\sum_{x_r}^M log(D(x_r)) + \frac{1}{M}\sum_{x_f}^M log(1-D(x_f))) \label{discriminator_loss_1}
\end{equation}

为便于计算与表示,可将等式转化为如下的等价形式,即讲整体的交叉熵期望转换为对真假样本交叉熵各自期望的和。

\begin{equation}
Loss_D = E_{x_r} \left [ -log(D(x_r)) \right ] + E_{x_f} \left [ -log(1-D(x_f)) \right ] \label{discriminator_loss_2}
\end{equation}

其中$ x_f $特指生成器生成的假样本,一般使用$ G(z) $表示,$ z $为服从正太分布$ p(z) $的随机向量,而使用$ x $表示收集的样本集中的样本(图片)。则最终将判别器损失函数定义为:
\begin{equation}
Loss_D = - \lbrace E_{x\sim p_{data}(x)} \left [ logD(x) \right ] + E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \rbrace \label{discriminator_loss_3}
\end{equation}

4.2.2 生成器损失

生成器(Generator)的优化目标是让生成器的输出$ x_f $尽可能以假乱真,即判别器对生成器生成的样本判为$ 1 $(为真)的概率越高越好。

那么,如果一个样本$ x $是真实的(real),$ p $则为$ 1 $,$ q $为$ D(x_r) $,其交叉熵为:

\begin{align}
\nonumber
H(L|D_r) &= -(plog(q)+(1-p)log(1-q))\\ \nonumber
&= -(1 \times logD(x_r)+(1-1) \times log(1-D(x_r))\\
&= -logD(x_r) \label{generator_real_entropy}
\end{align}

事实上,生成器G不关心真实样本(real)的情况,它只考虑其生成的$ x_f $是否可以欺骗判别器。从公式\eqref{generator_real_entropy}中也可以看出,在训练生成器时,对于真实样本的交叉熵$ -logD(x_r) $为固定值,并不会因生成器的优劣而变化。

如果一个样本是生成器生成的,即为假的(fake),$ p $则为$ 0 $,$ q $为$ D(x_f) $,其交叉熵为:

\begin{align}
\nonumber
H(L|D_f) &= -(plog(q)+(1-p)log(1-q))\\ \nonumber
&= -(0 \times logD(x_f)+(1-0) \times log(1-D(x_f))\\
&= -log(1-D(x_f)) \label{generator_fake_entropy}
\end{align}

于是,对于一个同时含有真实样本(real)与生成器生成样本(fake)的样本集,其交叉熵的平均值(期望)为:

\begin{equation}
H(L|D) = -\frac{1}{M}(\sum_{x_r}^M log(D(x_r)) + \sum_{x_f}^M log(1-D(x_f))) \label{generator_entropy}
\end{equation}

如上所述,生成器的优化目标让其的输出$ x_f $尽可能以假乱真,交叉熵公式\eqref{generator_entropy}代表了判别器鉴别假样本的能力。对于一个确定的假样本,交叉熵越小,意味着判别器对假样本的判别结果概率分布与生成器生成的假样本概率分布差距越小。而在判别器模型固定的情况下,如果这个交叉熵越大,则说明生成器生成的样本可以欺骗判别器,达到以假乱真的效果。所以,生成器的优化目标可以描述为在判别器模型固定的情况下最大化交叉熵,进而将判别器损失定义为:

\begin{equation}
Loss_G = -H(L|D) = \frac{1}{M}\sum_{x_r}^M log(D(x_r)) + \frac{1}{M}\sum_{x_f}^M log(1-D(x_f)) \label{generator_loss_1}
\end{equation}

为便于计算与表示,可将等式转化为如下的等价形式,即讲整体的交叉熵期望转换为对真假样本交叉熵各自期望的和。

\begin{equation}
Loss_G = E_{x_r} \left [ -log(D(x_r)) \right ] + E_{x_f} \left [ -log(1-D(x_f)) \right ] \label{generator_loss_2}
\end{equation}

由于在训练生成器时,公式中$ E_{x_r} \left [ -log(D(x_r)) \right ] $为固定值,所以生成器损失可以简化为

\begin{equation}
Loss_G = E_{x_f} \left [ -log(1-D(x_f)) \right ] \label{generator_loss_3}
\end{equation}

其中$ x_f $特指生成器生成的假样本,一般使用$ G(z) $表示,$ z $为服从正太分布$ p(z) $的随机向量。则最终将生成器损失函数定义为:

\begin{equation}
Loss_G = E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \label{generator_loss_4}
\end{equation}

4.2.3 整体损失函数表示

现在我们再来看Ian Goodfellow提出的GAN损失函数,就能比较好的理解了。

\begin{equation}
\min_G \max_D V(D,G) = E_{x\sim p_{data}(x)} \left [ logD(x) \right ] + E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \nonumber
\end{equation}

如2.2所述,在训练GAN的过程中,我们会迭代训练判别器与生成器。具体来说,先固定生成器不动,将判别器训练到一定程度;然后固定判别器,再进一步训练生成器;然后固定生成器,训练判别器……

对于判别器,在生成器固定不动的情况下,最大化优化函数:

\begin{equation}
\max_D V(D) = E_{x\sim p_{data}(x)} \left [ logD(x) \right ] + E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \nonumber
\end{equation}

其等价于优化(最小化)4.2.1中的判别器损失函数\eqref{discriminator_loss_3}:

\begin{equation}
Loss_D = - \lbrace E_{x\sim p_{data}(x)} \left [ logD(x) \right ] + E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \rbrace \nonumber
\end{equation}

对于生成器,在判别器固定不动的情况下,最小化优化函数:

\begin{equation}
\min_G V(G) = E_{x\sim p_{data}(x)} \left [ logD(x) \right ] + E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \nonumber
\end{equation}

其中等式的前一项$ E_{x\sim p_{data}(x)} \left [ logD(x) \right ] $不会随着生成器的训练发生变化,即为一个常量,则优化函数可简化为:

\begin{equation}
\min_G V(G) = E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \nonumber
\end{equation}

其等价于优化(最小化)4.2.2中的生成器损失函数\eqref{generator_loss_4}:
\begin{equation}
Loss_G = E_{z\sim p_z(z)} \left [ log(1-D(G(z))) \right ] \nonumber
\end{equation}

5 生成对抗的本质作用

相信通过上文你已经彻底理解了Ian Goodfellow提出的GAN原理与其损失函数定义。本节将解释GAN中生成器与判别器迭代训练时的具体关系,并说明生成器的本质作用。
图5:GAN训练过程
图5展示了GAN的训练过程,其中:

  • 蓝线:判别模型的分布$ D $(线中点为样本点,样本点越高,表示其为真实样本的概率越大)
  • 黑虚线:真实数据分布P$ (x) $
  • 绿实线:生成模型分布$ G $
  • $ x $线:真实样本数据
  • $ z $线:随机向量,一般为正太分布(G的输入)

(a)为训练最初阶段。$ x $是真实样本数据,其始终服从黑虚线的概率分布(假设为正太分布)。随机向量$ z $通过生成器转变为样本。但由于初始状态的生成器效果差,无法有效拟合真实样本数据,即生成器模型分布(绿实现)的均值偏离真实数据分布(黑虚线)的均值。而初始状态的判别器效果同样较差,其分布有强烈波动(蓝线)。

(b)过程首先固定生成器,训练判别器,使判别器可以准确的判断真样本x和假样本$ G(z) $。可以看到图中判别器(蓝线)在生成器分布(绿线)均值处的值明显下降,即判断其为真实样本的概率下降。

(c) 过程固定判别器,训练生成器。生成器在得到判别器在原始G分布的均值处判真概率下降后,调整生成器的分布,使其均值避开判别模型分布概率较低的区域,进而使其分布逐渐靠近真实数据分布$ P(x) $。

循环(b)(c),最终使生成模型分布G完全拟合真实数据分布$ P(x) $,在这种情况下判别器对真实样本和生成的假样本输出的判真概率相同,即无法辨别生成器产生的假样本,此时训练结束。

从结果上来看,生成器的作用是将随机向量$ z $映射到真实样本$ x $上。其通过不断与判别器对抗,尝试调整自身分布,最后将生成模型输出分布$ G $拟合为真实数据分布$ P(x) $。一般来讲,最后我们得到的生成器可以将符合某种分布的输入转换为目标分布的样本输出。


- - - - - - - - - - - - - - - - 本 文 结 束 啦 感 谢 您 阅 读 - - - - - - - - - - - - - - - -