DCGAN——菜鳥實現
收穫
在復現這個專案以前,我算是一個完全不入門的人。
所以,第一遍我花裡很大的精力取讀懂程式碼,第二遍根據視訊去理清思路,第三遍根據tensorflow框架的學習去程式碼中尋找他的身影。所以,整個專案下來,寫的可能水平參差不齊,我不清楚要怎麼表達,怎麼表達出來,更多的是這個過程的記錄,你會看到各個過程的身影。
首先,我明白了順序的重要性。先看論文,再看程式碼是一個不錯的選擇。這一次由於沒有思路,所以先看程式碼,再看得論文,所以第一遍有無數疑惑在腦中,直到第二遍才理清楚。
其次,抵消了對tensorflow程式碼的恐懼。人對未知的事物總是感到不安,對我而言,以前復現程式碼時總是擔憂著,我只是能跑出來,但這程式碼是什麼樣的?這回終於安心裡,他的程式碼結構是這個樣子,當然,掌握的還不夠熟練,以後肯定需要多次溫習。
再然後,簡單學習了tensorflow框架,體會到了框架的美妙和強大,簡潔的背後是巧妙地封裝。
最後,這次並沒有將整個專案程式碼,一行一行解讀完,只重點解讀了main.py和model.py這兩個最重要的檔案,其餘檔案中涉及到的函式大部分也都有說明。
最最後,很欣慰自己做了這件事兒,我覺得這才算我真正的Hello world!
程式碼思路
感覺從程式碼裡學了很多,雖然沒有完全消化完。
這份程式碼,並不算是原始碼,怎麼說,整個下來一遍,個人覺得,程式碼裡有部分刪減痕跡。當然這不是壞處,因為不刪減我們可能跑不了,因為可能作者寫程式碼時,基於的是自己的電腦配置,GPU情況等。
整個程式碼最後給我的感覺是,很嚴謹,你會發現作者很多地方都在注意tensorflow的版本問題,即注意程式碼相容性,對比以前跑過的程式碼,這可能是比較良心的一個了。
這份程式碼的本質並不難,就是GAN的本質。首先看G——generator,作用就是輸入一個維度定好的噪聲向量Z,根據反捲積,當然,是原論文的反捲積框架(PS:我看到的所有的DCGAN的程式碼解釋,都沒有說這個框架為什麼這樣,只是說原論文怎樣,這裡我沒有仔細拜讀,就不再解釋),反捲積,就是一個上取樣,通俗的說一個[1,10]大小的向量怎麼變成[256,256]的圖片,就是通過上取樣實現的,更通俗講就是不斷讓它變大,而這裡用反捲積實現,它的權重引數等等都是自動學習,也就是,你需要花點功夫考慮反捲積的維度大小的設計和組合,其他的都交給框架和電腦。當然,其中還有啟用函式,batch_norm等等細節就不介紹了。對於這些細節我只知道怎麼用,知道他們的優點,但為什麼用這個不用其他的,我也愛莫能助。最後總結一下:GAN中generotor目的就是生成圖片,這裡我們只不過把這個過程用反捲積實現了。
作者程式碼裡另外有一個sampler(這裡沒有細細研究),結構甚至程式碼和generotor一模一樣,不明白他這樣設計有啥用,當然,他的作用沒有體現在train裡面,體現在顯示裡面了。換句話說,你根據已有的模型或者訓練好的模型看生成圖片效果,或者訓練過程中看效果,它的作用就體現出來了。
D—discriminator算是最簡單的了,正常的卷積操作,最後輸出結果一個(0—1)評分值。這也是GAN的原理,對於discriminator而言,輸入一張圖片,網路給他打分,即輸出一個數,整個過程跟CNN多像。當然這裡DCGAN也確實用了卷積。
優化,論文這裡用了Adam,恕我直言,以前我只知道SGD這種東西,學習完,知道這東西還可以加衝量,作用就是穿越峽谷,避免震盪(具體自己學習吧),總的來說就是這裡用起來比SGD好。當然,在這之前你要去求網路損失,程式碼裡用交叉熵,它求了兩個(GAN原理),利用D分別去給維度一樣的真實圖片和生成圖片打分,分別和期望分值,前者為1後者為0,求交叉熵,然後構造Adma優化器優化。(這裡,我尤記得學過的GAN優化是分別固定G和D的引數去優化另一個,這裡用了tesnroflow框架,我著實沒有看出這個效果,不過它確實有這個趨勢,先優化d_loss再優化g_loss,不過細節沒看出來)
ok,你以為完了?不,你前面所有的都是在搭積木,tensorflow的靜態圖設計理念就是這樣,先搭好積木,再去運算。
運算時就涉及到了資料下載,打亂,分batch,然後迴圈餵給run(),當然,一定迴圈次數下去儲存模型和生成一定維度的樣本圖片看效果。
大部分過程就這樣,有的我可能也沒注意到,當然最主要是時間有限,不允許我再花時間再這個上了,具體程式碼裡還有很多關於視覺化,引數共享,GPU限速,版本相容,命令列引數,資料讀取,圖片處理(等等),這些零碎的東西有興趣的可以自己看,放在這裡太亂了。當然不嫌棄亂的話可以去看我寫的md檔案——賊亂。
- 補充: 由於我都是線下寫的,其他都有圖片,放上來不能正常顯示,只能放上這兩個,而且為什麼這排版會變成這樣…