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=0∑n(yj∗log(yj′)+(1−yj)∗log(1−yj′))
= ∑ 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=0∑n(−nyj∗log(yj′)+(−n1−yj∗log(1−yj′)))
其中,正样本的预测概率为 y j ′ y_j' yj′,真实概率为 y j n \frac{y_j}{n} nyj;负样本的预测概率为 1 − y j ′ 1-y_j' 1−yj′,真实概率为 1 − y j n \frac{1-y_j}{n} n1−yj。
对应的真样本的预测概率为 D ( x ) D(x) D(x),真实概率为 P d a t a ( x ) P_{data}(x) Pdata(x);假样本的预测概率为 1 − D ( x ˉ ) 1-D(\bar x) 1−D(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=0∑m(Pdata(x)∗log(D(x))+Pz(z)∗log(1−D(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=0∑m(Pdata(x)∗log(D(x)))−j=0∑m(Pz(z)∗log(1−D(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))] Ex∼Pdata(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(1−D(xˉ)))表示对 P z ( z ) ∗ l o g ( 1 − D ( x ˉ ) ) P_z(z)*log(1-D(\bar x)) Pz(z)∗log(1−D(xˉ))(即假样本的信息熵)求和,也可以看成对 1 − l o g ( D ( x ) 1-log(D(x) 1−log(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))] Ez∼Pz(z)[log(1−D(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=Ex∼Pdata(x)[log(D(x))]+Ez∼Pz(z)[log(1−D(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=0∑m(Pdata(xj)∗log(D(xj))+Pz(z)∗log(1−D(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(1−D(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 ∂D∂LD=Pdata(x)∗D1+Pz(z)∗1−D1=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)+1−DPz(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)=Ex∼Pdata(x)[log(Pdata(x)+Pz(z)Pdata(x))]+Ez∼Pz(z)[log(1−Pdata(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)})] =Ex∼Pdata(x)[log(Pdata(x)+Pz(z)Pdata(x))]+Ez∼Pz(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(p∣∣q)=∫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)))dx−log(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) =2∗21∗KL(Pdata(x)∣∣2(Pdata(x)+Pz(z)))+2∗21∗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 ) + 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∗[21∗KL(Pdata(x)∣∣2(Pdata(x)+Pz(z)))+21∗KL(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)≤2−log(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)=2−log(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=0∑m(Pdata(xj)∗log(D(xj))+Pz(z)∗log(1−D(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=0∑m(Pz(z)∗log(1−D(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(1−D(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(1−D(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=0∑m(Pdata(xj)∗log(D(xj))+Pz(z)∗log(1−D(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=0∑m(m1∗log(D(xj))+m1∗log(1−D(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=0∑m(log(D(xj))+log(1−D(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=0∑mm1∗log(1−D(xˉj))=m1j=0∑mlog(1−D(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=0∑m(yj∗log(D(xj))+(1−yj)∗log(1−D(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=0∑m(yj∗log(1−D(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)) −m1∑j=0myj∗log(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)) −m1∑j=0m(1−yj)∗log(1−D(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=0∑m(yj∗log(D(xj))+(1−yj)∗log(1−D(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=0∑myj∗log(D(xˉj)),(4)
这和我们得到的公式(3)不一样啊?为什么?
这是因为最小化公式(3)等价于最小化公式(4)。
一种理解是:公式(4)添加了符号,刚好抵消了 l o g ( 1 − D ( x ˉ j ) ) log(1-D(\bar x_j)) log(1−D(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(1−D(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(1−D(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训练的几个问题
训练不稳定