生成模型经典网络之GAN剖析

GAN[2014.6]
CGAN[2014.11]
VAE[2015.12]
infoGAN[2016.6]
EBGAN[2016.9]
ACGAN[2016.10]
LSGAN[2016.11]
WGAN[2017.1]
BEGAN[2017.3]
WGAN-GP[2017.3]
DRAGAN[2017.5]
SAGAN[2018.5]

GAN启发自博弈论中的二人零和博弈。GAN是由两部分主成:生成模型 G G G(generative model)和判别模型 D D D(discriminative model)。生成模型模仿真实样本的分布,判别模型是一个二分类器,判别输入是真实数据还是生成的样本。

x x x是真实数据,真实数据服从 P d a t a ( x ) P_{data}(x) Pdata(x)分布。 z z z是噪声数据,噪声数据服从 P z ( z ) P_z(z) Pz(z)分布,比如高斯分布或者均匀分布。然后从噪声 z z z进行抽样,通过 G G G之后生成假数据 x ˉ = G ( z ) \bar x=G(z) xˉ=G(z)。然后真实数据 x x x与生成数据 x ˉ \bar x xˉ一起输入分类器 D D D,输出判定结果即D(x)和D(G(x))。判别器 D D D是一个二分类器,其输出结果取值范围在[0,1]之间。


在一般的二分类器中,如果采用交叉熵损失函数,有:
L = − 1 n ∑ j = 0 n ( y j ∗ l o g ( y j ′ ) + ( 1 − y j ) ∗ l o g ( 1 − y j ′ ) ) L=-\frac{1}{n}\sum_{j=0}^n\biggl(y_j*log(y_j')+(1-y_j)*log(1-y_j')\biggr) L=n1j=0n(yjlog(yj)+(1yj)log(1yj))
= ∑ j = 0 n ( − y j n ∗ l o g ( y j ′ ) + ( − 1 − y j n ∗ l o g ( 1 − y j ′ ) ) ) =\sum_{j=0}^n\biggl(-\frac{y_j}{n}*log(y_j')+(-\frac{1-y_j}{n}*log(1-y_j'))\biggr) =j=0n(nyjlog(yj)+(n1yjlog(1yj)))
其中,正样本的预测概率为 y j ′ y_j' yj,真实概率为 y j n \frac{y_j}{n} nyj;负样本的预测概率为 1 − y j ′ 1-y_j' 1yj,真实概率为 1 − y j n \frac{1-y_j}{n} n1yj
对应的真样本的预测概率为 D ( x ) D(x) D(x),真实概率为 P d a t a ( x ) P_{data}(x) Pdata(x);假样本的预测概率为 1 − D ( x ˉ ) 1-D(\bar x) 1D(xˉ),真实概率为 P z ( z ) P_z(z) Pz(z)

还是要顺带说明下:分类器输出的是正样本的概率。

我们知道交叉熵损失函数反应的是所有样本的信息熵之和,所以,照猫画虎,有:
L = − ∑ j = 0 m ( P d a t a ( x ) ∗ l o g ( D ( x ) ) + P z ( z ) ∗ l o g ( 1 − D ( x ˉ ) ) ) L=-\sum_{j=0}^m\biggl(P_{data}(x)*log(D(x))+P_z(z)*log(1-D(\bar x))\biggr) L=j=0m(Pdata(x)log(D(x))+Pz(z)log(1D(xˉ)))

= − ∑ j = 0 m ( P d a t a ( x ) ∗ l o g ( D ( x ) ) ) − ∑ j = 0 m ( P z ( z ) ∗ l o g ( 1 − D ( x ˉ ) ) ) =-\sum_{j=0}^m\biggl(P_{data}(x)*log(D(x))\biggr)-\sum_{j=0}^m\biggl(P_z(z)*log(1-D(\bar x))\biggr) =j=0m(Pdata(x)log(D(x)))j=0m(Pz(z)log(1D(xˉ)))
其中:
∑ j = 0 m ( P d a t a ( x ) ∗ l o g ( D ( x ) ) ) \sum_{j=0}^m\biggl(P_{data}(x)*log(D(x))\biggr) j=0m(Pdata(x)log(D(x)))表示对 P d a t a ( x ) ∗ l o g ( D ( x ) ) P_{data}(x)*log(D(x)) Pdata(x)log(D(x))(即真样本的信息熵)求和,也可以看成对 l o g ( D ( x ) log(D(x) log(D(x)求期望(平均),所以可写成 E x ∼ P d a t a ( x ) [ l o g ( D ( x ) ) ] \Bbb E_{x\sim P_{data}(x)}[log(D(x))] ExPdata(x)[log(D(x))]
∑ j = 0 m ( P z ( z ) ∗ l o g ( 1 − D ( x ˉ ) ) ) \sum_{j=0}^m\biggl(P_z(z)*log(1-D(\bar x))\biggr) j=0m(Pz(z)log(1D(xˉ)))表示对 P z ( z ) ∗ l o g ( 1 − D ( x ˉ ) ) P_z(z)*log(1-D(\bar x)) Pz(z)log(1D(xˉ))(即假样本的信息熵)求和,也可以看成对 1 − l o g ( D ( x ) 1-log(D(x) 1log(D(x)求期望,所以可写成 E z ∼ P z ( z ) [ l o g ( 1 − D ( x ˉ ) ) ] \Bbb E_{z\sim P_z(z)}[log(1-D(\bar x))] EzPz(z)[log(1D(xˉ))]

于是就有了GAN原论文中判别器 D D D的损失函数:
L D = E x ∼ P d a t a ( x ) [ l o g ( D ( x ) ) ] + E z ∼ P z ( z ) [ l o g ( 1 − D ( x ˉ ) ) ] L_D=\Bbb E_{x\sim P_{data}(x)}[log(D(x))]+\Bbb E_{z\sim P_z(z)}[log(1-D(\bar x))] LD=ExPdata(x)[log(D(x))]+EzPz(z)[log(1D(xˉ))]

我们推导出的损失函数 L = − L D L=-L_D L=LD,主要是为了和原论文保持一致。

在离散情况下有:
L D = ∑ j = 0 m ( P d a t a ( x j ) ∗ l o g ( D ( x j ) ) + P z ( z ) ∗ l o g ( 1 − D ( x ˉ j ) ) ) L_D=\sum_{j=0}^m\biggl(P_{data}(x_j)*log(D(x_j))+P_z(z)*log(1-D(\bar x_j))\biggr) LD=j=0m(Pdata(xj)log(D(xj))+Pz(z)log(1D(xˉj)))

可以看到输入的是 m m m x j x_j xj m m m x ˉ j \bar x_j xˉj,共有 2 m 2m 2m个输入。

在连续情况下有:
L D = ∫ P d a t a ( x j ) ∗ l o g ( D ( x j ) ) + P z ( z ) ∗ l o g ( 1 − D ( x ˉ j ) ) d x L_D=\int P_{data}(x_j)*log(D(x_j))+ P_z(z)*log(1-D(\bar x_j))dx LD=Pdata(xj)log(D(xj))+Pz(z)log(1D(xˉj))dx

要让判别器 D D D表现最好就是要最大化 L D L_D LD,对应的方法是梯度上升法。这是很常见的最优化问题,最优化包括最大化和最小化,通常我们对其求导并让导数为0来获得最优解,这里我们将 D ( x ) D(x) D(x) D ( x ˉ ) D(\bar x) D(xˉ)看作单一变量 D D D,则有:
∂ L D ∂ D = P d a t a ( x ) ∗ 1 D + P z ( z ) ∗ 1 1 − D = 0 \frac{ \partial L_D}{\partial D}=P_{data}(x)*\frac{1}{D}+P_z(z)*\frac{1}{1-D}=0 DLD=Pdata(x)D1+Pz(z)1D1=0
P d a t a ( x ) D + P z ( z ) 1 − D = 0 \frac{P_{data}(x)}{D}+\frac{P_z(z)}{1-D}=0 DPdata(x)+1DPz(z)=0
⇒ D ∗ = P d a t a ( x ) P d a t a ( x ) + P z ( z ) \Rightarrow D^*=\frac{P_{data}(x)}{P_{data}(x)+P_z(z)} D=Pdata(x)+Pz(z)Pdata(x)
(数学中函数 f f f的最优解 x x x可以写成 x ∗ x^* x

也就是说当 D ( x ) = D ( x ˉ ) = D ∗ = P d a t a ( x ) P d a t a ( x ) + P z ( z ) D(x)=D(\bar x)=D^*=\frac{P_{data}(x)}{P_{data}(x)+P_z(z)} D(x)=D(xˉ)=D=Pdata(x)+Pz(z)Pdata(x)的时候损失函数最优,即:
o p t i m u m ( L D ) = E x ∼ P d a t a ( x ) [ l o g ( P d a t a ( x ) P d a t a ( x ) + P z ( z ) ) ] + E z ∼ P z ( z ) [ l o g ( 1 − P d a t a ( x ) P d a t a ( x ) + P z ( z ) ) ] optimum(L_D)=\Bbb E_{x\sim P_{data}(x)}[log(\frac{P_{data}(x)}{P_{data}(x)+P_z(z)})]+\Bbb E_{z\sim P_z(z)}[log(1-\frac{P_{data}(x)}{P_{data}(x)+P_z(z)})] optimum(LD)=ExPdata(x)[log(Pdata(x)+Pz(z)Pdata(x))]+EzPz(z)[log(1Pdata(x)+Pz(z)Pdata(x))]
= E x ∼ P d a t a ( x ) [ l o g ( P d a t a ( x ) P d a t a ( x ) + P z ( z ) ) ] + E z ∼ P z ( z ) [ l o g ( P z ( z ) P d a t a ( x ) + P z ( z ) ) ] =\Bbb E_{x\sim P_{data}(x)}[log(\frac{P_{data}(x)}{P_{data}(x)+P_z(z)})]+\Bbb E_{z\sim P_z(z)}[log(\frac{P_z(z)}{P_{data}(x)+P_z(z)})] =ExPdata(x)[log(Pdata(x)+Pz(z)Pdata(x))]+EzPz(z)[log(Pdata(x)+Pz(z)Pz(z))]
= ∫ P d a t a ( x ) ∗ l o g ( P d a t a ( x ) P d a t a ( x ) + P z ( z ) ) d x + ∫ P z ( z ) ∗ l o g ( P z ( z ) P d a t a ( x ) + P z ( z ) ) d x =\int P_{data}(x)*log(\frac{P_{data}(x)}{P_{data}(x)+P_z(z)})dx+ \int P_z(z)*log(\frac{P_z(z)}{P_{data}(x)+P_z(z)})dx =Pdata(x)log(Pdata(x)+Pz(z)Pdata(x))dx+Pz(z)log(Pdata(x)+Pz(z)Pz(z))dx
写出这个形状已经和KL散度的公式( K L ( p ∣ ∣ q ) = ∫ p ( x ) l o g p ( x ) q ( x ) d x KL(p||q)=\int p(x)log\frac{p(x)}{q(x)}dx KL(pq)=p(x)logq(x)p(x)dx)一模一样了,但是这还不够,我们继续变形:
= ∫ P d a t a ( x ) ∗ l o g ( 1 2 ∗ P d a t a ( x ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) d x + ∫ P z ( z ) ∗ l o g ( 1 2 ∗ P z ( z ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) ) d x =\int P_{data}(x)*log(\frac{1}{2}*\frac{P_{data}(x)}{(P_{data}(x)+P_z(z))/2})dx+ \int P_z(z)*log(\frac{1}{2}*\frac{P_z(z)}{(P_{data}(x)+P_z(z))/2}))dx =Pdata(x)log(21(Pdata(x)+Pz(z))/2Pdata(x))dx+Pz(z)log(21(Pdata(x)+Pz(z))/2Pz(z)))dx
= ∫ P d a t a ( x ) ∗ l o g ( P d a t a ( x ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) d x + ∫ P d a t a ( x ) ∗ l o g ( 1 2 ) d x + ∫ P z ( z ) ∗ l o g ( P z ( z ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) ) d x + ∫ P z ( z ) ∗ l o g ( 1 2 ) d x =\int P_{data}(x)*log(\frac{P_{data}(x)}{(P_{data}(x)+P_z(z))/2})dx+\int P_{data}(x)*log(\frac{1}{2})dx+ \int P_z(z)*log(\frac{P_z(z)}{(P_{data}(x)+P_z(z))/2}))dx+\int P_z(z)*log(\frac{1}{2})dx =Pdata(x)log((Pdata(x)+Pz(z))/2Pdata(x))dx+Pdata(x)log(21)dx+Pz(z)log((Pdata(x)+Pz(z))/2Pz(z)))dx+Pz(z)log(21)dx
= ∫ P d a t a ( x ) ∗ l o g ( P d a t a ( x ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) d x + l o g ( 1 2 ) + ∫ P z ( z ) ∗ l o g ( P z ( z ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) ) d x + l o g ( 1 2 ) =\int P_{data}(x)*log(\frac{P_{data}(x)}{(P_{data}(x)+P_z(z))/2})dx+log(\frac{1}{2})+ \int P_z(z)*log(\frac{P_z(z)}{(P_{data}(x)+P_z(z))/2}))dx+log(\frac{1}{2}) =Pdata(x)log((Pdata(x)+Pz(z))/2Pdata(x))dx+log(21)+Pz(z)log((Pdata(x)+Pz(z))/2Pz(z)))dx+log(21)
= ∫ P d a t a ( x ) ∗ l o g ( P d a t a ( x ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) d x + ∫ P z ( z ) ∗ l o g ( P z ( z ) ( P d a t a ( x ) + P z ( z ) ) / 2 ) ) d x − l o g ( 4 ) =\int P_{data}(x)*log(\frac{P_{data}(x)}{(P_{data}(x)+P_z(z))/2})dx+\int P_z(z)*log(\frac{P_z(z)}{(P_{data}(x)+P_z(z))/2}))dx-log(4) =Pdata(x)log((Pdata(x)+Pz(z))/2Pdata(x))dx+Pz(z)log((Pdata(x)+Pz(z))/2Pz(z)))dxlog(4)
= K L ( P d a t a ( x ) ∣ ∣ ( P d a t a ( x ) + P z ( z ) ) 2 ) + K L ( P z ( z ) ∣ ∣ ( P d a t a ( x ) + P z ( z ) ) 2 ) − l o g ( 4 ) =KL(P_{data}(x)||\frac{(P_{data}(x)+P_z(z))}{2})+KL(P_z(z)||\frac{(P_{data}(x)+P_z(z))}{2})-log(4) =KL(Pdata(x)2(Pdata(x)+Pz(z)))+KL(Pz(z)2(Pdata(x)+Pz(z)))log(4)
= 2 ∗ 1 2 ∗ K L ( P d a t a ( x ) ∣ ∣ ( P d a t a ( x ) + P z ( z ) ) 2 ) + 2 ∗ 1 2 ∗ K L ( P z ( z ) ∣ ∣ ( P d a t a ( x ) + P z ( z ) ) 2 ) − l o g ( 4 ) =2*\frac{1}{2}*KL(P_{data}(x)||\frac{(P_{data}(x)+P_z(z))}{2})+2*\frac{1}{2}*KL(P_z(z)||\frac{(P_{data}(x)+P_z(z))}{2})-log(4) =221KL(Pdata(x)2(Pdata(x)+Pz(z)))+221KL(Pz(z)2(Pdata(x)+Pz(z)))log(4)
= 2 ∗ [ 1 2 ∗ K L ( P d a t a ( x ) ∣ ∣ ( P d a t a ( x ) + P z ( z ) ) 2 ) + 1 2 ∗ K L ( P z ( z ) ∣ ∣ ( P d a t a ( x ) + P z ( z ) ) 2 ) ] − l o g ( 4 ) =2*[\frac{1}{2}*KL(P_{data}(x)||\frac{(P_{data}(x)+P_z(z))}{2})+\frac{1}{2}*KL(P_z(z)||\frac{(P_{data}(x)+P_z(z))}{2})]-log(4) =2[21KL(Pdata(x)2(Pdata(x)+Pz(z)))+21KL(Pz(z)2(Pdata(x)+Pz(z)))]log(4)
= 2 J S ( P d a t a ( x ) ∣ ∣ P z ( z ) ) − l o g ( 4 ) =2JS(P_{data}(x)||P_z(z))-log(4) =2JS(Pdata(x)Pz(z))log(4)

其中KL表示KL散度,JS表示JS散度。

∵ \because JS散度取值在[0,1]之间

∴ \therefore − l o g ( 4 ) ≤ o p t i m u m ( L D ) ≤ 2 − l o g ( 4 ) -log(4) \leq optimum(L_D) \leq2-log(4) log(4)optimum(LD)2log(4)

我们知道JS散度是衡量两个概率分布的相似度的,即如果两个两个概率分布一模一样,那么JS散度为0;如果两个两个概率分布完全不同(没有重叠),那么JS散度为1。

当JS散度为1时, o p t i m u m ( L D ) = 2 − l o g ( 4 ) optimum(L_D)=2-log(4) optimum(LD)=2log(4)取得最大值,即 P d a t a ( x ) = − P z ( z ) P_{data}(x)=-P_z(z) Pdata(x)=Pz(z),即 D ∗ = 0 D^*=0 D=0,也就是说 G ( x ) G(x) G(x)生成的数据和真实数据完全不一样;
当JS散度为0时, o p t i m u m ( L D ) = − l o g ( 4 ) optimum(L_D)=-log(4) optimum(LD)=log(4)取得最小值,即 P d a t a ( x ) = P z ( z ) P_{data}(x)=P_z(z) Pdata(x)=Pz(z),即 D ∗ = 1 2 D^*=\frac{1}{2} D=21,也就是说 G ( x ) G(x) G(x)生成的数据和真实数据一模一样。


现在我们再来看看生成器 G G G,生成器输入的是噪音数据,输出的是和真实数据相同形状(shape)的假数据,比如输出一张图片,那么怎么评价生成器 G G G表现得好坏呢?

想想现实中的制假钞和验钞,生成器就好比制假钞机,判别器就是验钞机。制假钞机的好坏是通过验钞机来反映的。

同理,生成器表现得好坏是通过判别器来反映的。所以生成器的损失函数就是判别器的损失函数, L D L_D LD最大化对应判别器的性能最好;反之, L D L_D LD最小化对应判别器的性能最差。而生成器的目的就是让判别器性能表现最差,所以生成器就是要最小化 L D L_D LD,即: L G = L D = ∑ j = 0 m ( P d a t a ( x j ) ∗ l o g ( D ( x j ) ) + P z ( z ) ∗ l o g ( 1 − D ( x ˉ j ) ) ) , ( 1 ) L_G=L_D=\sum_{j=0}^m\biggl(P_{data}(x_j)*log(D(x_j))+P_z(z)*log(1-D(\bar x_j))\biggr), (1) LG=LD=j=0m(Pdata(xj)log(D(xj))+Pz(z)log(1D(xˉj))),(1)

可是,很多文章以及代码实现的生成器的损失函数是这样的:
L G = ∑ j = 0 m ( P z ( z ) ∗ l o g ( 1 − D ( x ˉ ) ) ) , ( 2 ) L_G=\sum_{j=0}^m\biggl(P_z(z)*log(1-D(\bar x))\biggr), (2) LG=j=0m(Pz(z)log(1D(xˉ))),(2)
这是为什么的呢?
这是因为最小化公式(1)等同于最小化公式(2)。我们在上面已经推导了公式(1)的最优化过程,当 D ∗ = P d a t a ( x ) P d a t a ( x ) + P z ( z ) D^*=\frac{P_{data}(x)}{P_{data}(x)+P_z(z)} D=Pdata(x)+Pz(z)Pdata(x)的时候 L D L_D LD达到最优,而当 P d a t a ( x ) = P z ( z ) P_{data}(x)=P_z(z) Pdata(x)=Pz(z)的时候 L D L_D LD最小。 P d a t a ( x ) = P z ( z ) P_{data}(x)=P_z(z) Pdata(x)=Pz(z)就意味着 P z ( z ) ∗ l o g ( 1 − D ( x ˉ j ) ) = 0 P_z(z)*log(1-D(\bar x_j))=0 Pz(z)log(1D(xˉj))=0,而 P z ( z ) P_z(z) Pz(z)是不可能为0的,所以 D ( x ˉ j ) = 1 D(\bar x_j)=1 D(xˉj)=1,这就是说 m m m个样本都被判别器判别为真了。

而最小化公式(2),就是让 D ( x ˉ j ) = 1 D(\bar x_j)=1 D(xˉj)=1,对应 ∑ j = 0 m ( P z ( z ) ∗ l o g ( 1 − D ( x ˉ ) ) ) = 0 \sum_{j=0}^m\biggl(P_z(z)*log(1-D(\bar x))\biggr)=0 j=0m(Pz(z)log(1D(xˉ)))=0,这个最小化公式(1)完全一致。


总结:
既然判别器和生成器的损失函数一样,那么就有GAN的损失函数为(和原论文一致的写法):
V ( G , D ) = ∑ j = 0 m ( P d a t a ( x j ) ∗ l o g ( D ( x j ) ) + P z ( z ) ∗ l o g ( 1 − D ( x ˉ j ) ) ) V(G,D)=\sum_{j=0}^m\biggl(P_{data}(x_j)*log(D(x_j))+P_z(z)*log(1-D(\bar x_j))\biggr) V(G,D)=j=0m(Pdata(xj)log(D(xj))+Pz(z)log(1D(xˉj)))
其中判别器的目标是最大化 V ( G , D m a x ) V(G,D_{max}) V(G,Dmax),这个过程叫梯度上升法;生成器的目标是最小化 V ( G m i n , D ) V(G_{min},D) V(Gmin,D),这个过程叫梯度下降法。

在实际代码中,我们习惯于最小化损失函数,所以针对判别器的损失函数 L D L_D LD的右侧取负,将最大化变成最小化,对应的梯度上升法变成梯度下降法。其次,真实样本的概率分布我们并不知道,所以我们对 P d a t a ( x ) P_{data}(x) Pdata(x) P z ( z ) P_z(z) Pz(z)都采用均匀分布。所以判别器的损失函数变为:
L D = − ∑ j = 0 m ( 1 m ∗ l o g ( D ( x j ) ) + 1 m ∗ l o g ( 1 − D ( x ˉ j ) ) ) L_D=-\sum_{j=0}^m\biggl(\frac{1}{m}*log(D(x_j))+\frac{1}{m}*log(1-D(\bar x_j))\biggr) LD=j=0m(m1log(D(xj))+m1log(1D(xˉj)))
= − 1 m ∑ j = 0 m ( l o g ( D ( x j ) ) + l o g ( 1 − D ( x ˉ j ) ) ) =-\frac{1}{m}\sum_{j=0}^m\biggl(log(D(x_j))+log(1-D(\bar x_j))\biggr) =m1j=0m(log(D(xj))+log(1D(xˉj)))

生成器的损失函数为:
L G = ∑ j = 0 m 1 m ∗ l o g ( 1 − D ( x ˉ j ) ) = 1 m ∑ j = 0 m l o g ( 1 − D ( x ˉ j ) ) L_G=\sum_{j=0}^m\frac{1}{m}*log(1-D(\bar x_j))=\frac{1}{m}\sum_{j=0}^mlog(1-D(\bar x_j)) LG=j=0mm1log(1D(xˉj))=m1j=0mlog(1D(xˉj))

要注意,既然判别器是个二分类器,那么就要有标签进行比对,显然上面的公式中我们没有引入标签。那么怎么引标签呢?可以参考交叉熵。引入标签之后的公式就是我们实际代码中的实现:
实际代码中判别器的损失函数为:
L D = − 1 m ∑ j = 0 m ( y j ∗ l o g ( D ( x j ) ) + ( 1 − y j ) ∗ l o g ( 1 − D ( x ˉ j ) ) ) L_D=-\frac{1}{m}\sum_{j=0}^m\biggl(y_j*log(D(x_j))+(1-y_j)*log(1-D(\bar x_j))\biggr) LD=m1j=0m(yjlog(D(xj))+(1yj)log(1D(xˉj)))

实际代码中生成器所用的损失函为:
L G = 1 m ∑ j = 0 m ( y j ∗ l o g ( 1 − D ( x ˉ j ) ) ) , ( 3 ) L_G=\frac{1}{m}\sum_{j=0}^m\biggl(y_j*log(1-D(\bar x_j))\biggr), (3) LG=m1j=0m(yjlog(1D(xˉj))),(3)

d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_real_logits, labels=tf.ones_like(D_real)))
# d_loss_fake=-log(sigmoid(D_fake_logits))等价于d_loss_fake=-log(D(G(z))
d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.zeros_like(D_fake)))
#d_loss为生成器和鉴别器传出的loss之和
self.d_loss = d_loss_real + d_loss_fake

# get loss for generator
#g_loss=-log(sigmoid(D_fake_logits))等价于g_loss=-log(D(G(z))
self.g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.ones_like(D_fake)))

# optimizers 优化器用于减小损失函数loss,采用Adam优化器,可直接用minimize
with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):
self.d_optim = tf.train.AdamOptimizer(self.learning_rate, beta1=self.beta1).minimize(self.d_loss,var_list=d_vars)
self.g_optim = tf.train.AdamOptimizer(self.learning_rate*5, beta1=self.beta1).minimize(self.g_loss,var_list=g_vars)

代码中tf.nn.sigmoid_cross_entropy_with_logits计算公式为:

label * -log(sigmoid(x)) + (1 - label ) * -log(1 - sigmoid(x))

当我们输入 m m m个标记为1的样本,实际计算的是 − 1 m ∑ j = 0 m y j ∗ l o g ( D ( x j ) ) -\frac{1}{m}\sum_{j=0}^my_j*log(D(x_j)) m1j=0myjlog(D(xj))
当我们输入 m m m个标记为0的样本,实际计算的是 − 1 m ∑ j = 0 m ( 1 − y j ) ∗ l o g ( 1 − D ( x ˉ j ) ) -\frac{1}{m}\sum_{j=0}^m(1-y_j)*log(1-D(\bar x_j)) m1j=0m(1yj)log(1D(xˉj))
所以d_loss和上面的公式是一样的。

可以代码中的g_loss是这样的:
L G = − 1 m ∑ j = 0 m ( y j ∗ l o g ( D ( x j ) ) + ( 1 − y j ) ∗ l o g ( 1 − D ( x ˉ j ) ) ) L_G=-\frac{1}{m}\sum_{j=0}^m\biggl(y_j*log(D(x_j))+(1-y_j)*log(1-D(\bar x_j))\biggr) LG=m1j=0m(yjlog(D(xj))+(1yj)log(1D(xˉj)))
由代码中可以看出和判别器损失函数一样,都是调用tf.nn.sigmoid_cross_entropy_with_logits。

因为输入的 m m m个标记为1的样本(总不能告诉验钞的说你验的是假钞吧!!!),所以实际计算的是:
L G = − 1 m ∑ j = 0 m y j ∗ l o g ( D ( x ˉ j ) ) , ( 4 ) L_G=-\frac{1}{m}\sum_{j=0}^my_j*log(D(\bar x_j)), (4) LG=m1j=0myjlog(D(xˉj)),(4)
这和我们得到的公式(3)不一样啊?为什么?
这是因为最小化公式(3)等价于最小化公式(4)。
一种理解是:公式(4)添加了符号,刚好抵消了 l o g ( 1 − D ( x ˉ j ) ) log(1-D(\bar x_j)) log(1D(xˉj))变成 l o g ( D ( x ˉ j ) ) log(D(\bar x_j)) log(D(xˉj))
另一种理解是:最小化公式(3)即让 D ( x ˉ j ) → 1 D(\bar x_j) \to 1 D(xˉj)1= l o g ( 1 − D ( x ˉ j ) ) → 0 log(1-D(\bar x_j))\to 0 log(1D(xˉj))0,这等价于公式(4)的 D ( x ˉ j ) → 1 D(\bar x_j) \to 1 D(xˉj)1= l o g ( D ( x ˉ j ) ) → 1 log(D(\bar x_j))\to 1 log(D(xˉj))1,即由公式(3)的 l o g ( 1 − D ( x ˉ j ) ) log(1-D(\bar x_j)) log(1D(xˉj)) = 公式(4)的 − l o g ( D ( x ˉ j ) ) -log(D(\bar x_j)) log(D(xˉj))

如上图,我们输入到判别器中的是 m m m个real样本+ m m m个fake样本,而输入到生成器中的是 m m m个噪音。

在这里插入图片描述

GAN中参数的更新?
常规的gan在更新G的时候,要把D锁住,然后G的目标是为了让D输出的得分越高越好。

GAN训练的几个问题
训练不稳定

猜你喜欢

转载自blog.csdn.net/weixin_38052918/article/details/107856412