先來梳理一下咱們以前所寫的代碼,原始的生成對抗網絡,所要優化的目標函數爲:git
此目標函數能夠分爲兩部分來看:網絡
①固定生成器 G,優化判別器 D, 則上式能夠寫成以下形式: 函數
能夠轉化爲最小化形式: 優化
咱們編寫的代碼中,d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = D_logits, labels = tf.ones_like(D))),因爲咱們判別器最後一層是 sigmoid ,因此能夠看出來 d_loss_real 是上式中的第一項(捨去常數機率 1/2),d_loss_fake 爲上式中的第二項。spa
②固定判別器 D,優化生成器 G,捨去前面的常數,至關於最小化:code
也至關於最小化:blog
咱們的代碼中,g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = D_logits_, labels = tf.ones_like(D))),完美對應上式。it
接下來開始咱們的 WGAN 之旅,正如 https://zhuanlan.zhihu.com/p/25071913 所介紹的,咱們要構建一個判別器 D,使得 D 的參數不超過某個固定的常數,最後一層是非線性層,而且使式子:class
達到最大,那麼 L 就能夠做爲咱們的 Wasserstein 距離,生成器的目標是最小化這個距離,去掉第一項與生成器無關的項,獲得咱們生成器的損失函數。咱們能夠把上式加個負號,做爲 D 的損失函數,其中加負號後的第一項,是 d_loss_real,加負號後的第二項,是 d_loss_fake。循環
下面開始碼代碼:
爲了方便,咱們直接在上一節咱們的 none_cond_DCGAN.py 文件中修改相應的代碼:
在開頭的宏定義中加入:
CLIP = [-0.01, 0.01]
CRITIC_NUM = 5
如圖:
註釋掉原來 discriminator 的 return,從新輸入一個 return 以下:
在 train 函數裏面,修改以下地方:
在循環裏面,要改以下地方,這裏稍微作一下說明,idx < 25 時 D 循環更新 25 次纔會更新 G,用來保證 D 的網絡大體知足 Wasserstein 距離,這是一個小小的 trick。
改完以後點擊運行進行訓練,WGAN 收斂速度很快,大約一千屢次迭代的時候,生成網絡生成的圖像已經很像了,最後生成的圖像以下,能夠看到,圖像仍是有些噪點和壞點的。
最後的最後,貼一張網絡的 Graph:
參考文獻:
1. https://zhuanlan.zhihu.com/p/25071913