生成式對(duì)抗網(wǎng)絡(luò)(GAN)是近年來大熱的深度學(xué)習(xí)模型。最近正好有空看了這方面的一些論文,跑了一個(gè) GAN 的代碼,于是寫了這篇文章來介紹一下 GAN而涉。
本文主要分為三個(gè)部分:
介紹原始的 GAN 的原理?
同樣非常重要的 DCGAN 的原理?
如何在 Tensorflow 跑 DCGAN 的代碼,生成如題圖所示的動(dòng)漫頭像联予,附送數(shù)據(jù)集哦 :-)
??一啼县、GAN 原理介紹
說到 GAN 第一篇要看的 paper 當(dāng)然是 Ian Goodfellow 大牛的 Generative Adversarial Networks,這篇 paper 算是這個(gè)領(lǐng)域的開山之作沸久。
GAN 的基本原理其實(shí)非常簡單季眷,這里以生成圖片為例進(jìn)行說明。假設(shè)我們有兩個(gè)網(wǎng)絡(luò)卷胯,G(Generator)和 D(Discriminator)子刮。正如它的名字所暗示的那樣,它們的功能分別是:
G 是一個(gè)生成圖片的網(wǎng)絡(luò)窑睁,它接收一個(gè)隨機(jī)的噪聲 z挺峡,通過這個(gè)噪聲生成圖片,記做 G(z)卵慰。
D 是一個(gè)判別網(wǎng)絡(luò),判別一張圖片是不是 “真實(shí)的”佛呻。它的輸入?yún)?shù)是 x裳朋,x 代表一張圖片,輸出 D(x)代表 x 為真實(shí)圖片的概率,如果為 1鲤嫡,就代表 100% 是真實(shí)的圖片送挑,而輸出為 0,就代表不可能是真實(shí)的圖片暖眼。
在訓(xùn)練過程中惕耕,生成網(wǎng)絡(luò) G 的目標(biāo)就是盡量生成真實(shí)的圖片去欺騙判別網(wǎng)絡(luò) D。而 D 的目標(biāo)就是盡量把 G 生成的圖片和真實(shí)的圖片分別開來诫肠。這樣司澎,G 和 D 構(gòu)成了一個(gè)動(dòng)態(tài)的 “博弈過程”。
最后博弈的結(jié)果是什么栋豫?在最理想的狀態(tài)下挤安,G 可以生成足以 “以假亂真” 的圖片 G(z)。對(duì)于 D 來說丧鸯,它難以判定 G 生成的圖片究竟是不是真實(shí)的蛤铜,因此 D(G(z)) = 0.5。
這樣我們的目的就達(dá)成了:我們得到了一個(gè)生成式的模型 G丛肢,它可以用來生成圖片围肥。
以上只是大致說了一下 GAN 的核心原理,如何用數(shù)學(xué)語言描述呢蜂怎?這里直接摘錄論文里的公式:
簡單分析一下這個(gè)公式:
整個(gè)式子由兩項(xiàng)構(gòu)成穆刻。x 表示真實(shí)圖片,z 表示輸入 G 網(wǎng)絡(luò)的噪聲派敷,而 G(z) 表示 G 網(wǎng)絡(luò)生成的圖片蛹批。
D(x) 表示?D 網(wǎng)絡(luò)判斷真實(shí)圖片是否真實(shí)的概率(因?yàn)?x 就是真實(shí)的,所以對(duì)于 D 來說篮愉,這個(gè)值越接近 1 越好)腐芍。而 D(G(z)) 是 D 網(wǎng)絡(luò)判斷 G 生成的圖片的是否真實(shí)的概率。
G 的目的:上面提到過试躏,D(G(z)) 是?D 網(wǎng)絡(luò)判斷 G 生成的圖片是否真實(shí)的概率猪勇,G 應(yīng)該希望自己生成的圖片 “越接近真實(shí)越好”。也就是說颠蕴,G 希望 D(G(z)) 盡可能得大泣刹,這時(shí) V(D, G) 會(huì)變小。因此我們看到式子的最前面的記號(hào)是 min_G犀被。
D 的目的:D 的能力越強(qiáng)椅您,D(x) 應(yīng)該越大,D(G(x)) 應(yīng)該越小寡键。這時(shí) V(D,G) 會(huì)變大掀泳。因此式子對(duì)于 D 來說是求最大 (max_D)
下面這幅圖片很好地描述了這個(gè)過程:
那么如何用隨機(jī)梯度下降法訓(xùn)練 D 和 G?論文中也給出了算法:
這里紅框圈出的部分是我們要額外注意的。第一步我們訓(xùn)練 D员舵,D 是希望 V(G, D) 越大越好脑沿,所以是加上梯度 (ascending)。第二步訓(xùn)練 G 時(shí)马僻,V(G, D) 越小越好庄拇,所以是減去梯度 (descending)。整個(gè)訓(xùn)練過程交替進(jìn)行韭邓。
??二措近、DCGAN 原理介紹
我們知道深度學(xué)習(xí)中對(duì)圖像處理應(yīng)用最好的模型是 CNN,那么如何把 CNN 與 GAN 結(jié)合仍秤?DCGAN 是這方面最好的嘗試之一(點(diǎn)擊查看論文)
DCGAN 的原理和 GAN 是一樣的熄诡,這里就不在贅述。它只是把上述的 G 和 D 換成了兩個(gè)卷積神經(jīng)網(wǎng)絡(luò)(CNN)诗力。但不是直接換就可以了凰浮,DCGAN 對(duì)卷積神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)做了一些改變,以提高樣本的質(zhì)量和收斂的速度苇本,這些改變有:
取消所有 pooling 層袜茧。G 網(wǎng)絡(luò)中使用轉(zhuǎn)置卷積(transposed convolutional layer)進(jìn)行上采樣,D 網(wǎng)絡(luò)中用加入 stride 的卷積代替 pooling瓣窄。
在 D 和 G 中均使用 batch normalization
去掉 FC 層笛厦,使網(wǎng)絡(luò)變?yōu)槿矸e網(wǎng)絡(luò)
G 網(wǎng)絡(luò)中使用 ReLU 作為激活函數(shù),最后一層使用 tanh
D 網(wǎng)絡(luò)中使用 LeakyReLU 作為激活函數(shù)
DCGAN 中的 G 網(wǎng)絡(luò)示意:
??三俺夕、DCGAN in Tensorflow
好了裳凸,上面說了一通原理,下面說點(diǎn)有意思的實(shí)踐部分的內(nèi)容劝贸。
DCGAN 的原作者用 DCGAN 生成 LSUN 的臥室圖片姨谷,這并不是特別有意思。之前在網(wǎng)上看到一篇文章 Chainer で顔イラストの自動(dòng)生成 - Qiita 映九,是用 DCGAN 生成動(dòng)漫人物頭像的梦湘,效果如下:
這是個(gè)很有趣的實(shí)踐內(nèi)容〖可惜原文是用 Chainer 做的捌议,這個(gè)框架使用的人不多。下面我們就在 Tensorflow 中復(fù)現(xiàn)這個(gè)結(jié)果引有。
1. 原始數(shù)據(jù)集的搜集
首先我們需要用爬蟲爬取大量的動(dòng)漫圖片瓣颅,原文是在這個(gè)網(wǎng)站:http://safebooru.donmai.us / 中爬取的。我嘗試的時(shí)候譬正,發(fā)現(xiàn)在我的網(wǎng)絡(luò)環(huán)境下無法訪問這個(gè)網(wǎng)站宫补,于是我就寫了一個(gè)簡單的爬蟲爬了另外一個(gè)著名的動(dòng)漫圖庫網(wǎng)站:konachan.net僻孝。
爬蟲代碼如下:
這個(gè)爬蟲大概跑了一天,爬下來 12 萬張圖片守谓,大概是這樣的:
可以看到這里面的圖片大多數(shù)比較雜亂,還不能直接作為數(shù)據(jù)訓(xùn)練您单,我們需要用合適的工具斋荞,截取人物的頭像進(jìn)行訓(xùn)練。
2. 頭像截取
截取頭像和原文一樣虐秦,直接使用 github 上一個(gè)基于 opencv 的工具:nagadomi平酿。
簡單包裝下代碼:
截取頭像后的人物數(shù)據(jù):
這樣就可以用來訓(xùn)練了!
如果你不想從頭開始爬圖片悦陋,可以直接使用我爬好的頭像數(shù)據(jù)(275M蜈彼,約 5 萬多張圖片):百度云盤 提取碼:g5qa
3. 訓(xùn)練
DCGAN 在 Tensorflow 中已經(jīng)有人造好了輪子:carpedm20/DCGAN,我們直接使用這個(gè)代碼就可以了俺驶。
不過原始代碼中只提供了有限的幾個(gè)數(shù)據(jù)庫幸逆,如何訓(xùn)練自己的數(shù)據(jù)?在 model.py 中我們找到讀數(shù)據(jù)的幾行代碼:
if config.dataset == 'mnist':
data_X, data_y = self.load_mnist()
else:
data = glob(os.path.join("./data", config.dataset, "*.jpg"))
這樣讀數(shù)據(jù)的邏輯就很清楚了暮现,我們?cè)?data 文件夾中再新建一個(gè) anime 文件夾还绘,把圖片直接放到這個(gè)文件夾里,運(yùn)行時(shí)指定 --dataset anime 即可栖袋。
運(yùn)行指令(參數(shù)含義:指定生成的圖片的尺寸為 48x48拍顷,我們圖片的大小是 96x96,跑 300 個(gè) epoch):
python main.py --image_size 96 --output_size 48 --dataset anime --is_crop True --is_train True --epoch 300
4. 結(jié)果
第 1 個(gè) epoch 跑完(只有一點(diǎn)點(diǎn)輪廓):
第 5 個(gè) epoch 之后的結(jié)果:
第 10 個(gè) epoch:
200 個(gè) epoch塘幅,仔細(xì)看有些圖片確實(shí)是足以以假亂真的:
題圖是我從第 300 個(gè) epoch 生成的昔案。
??四、總結(jié)和后續(xù)
簡單介紹了一下 GAN 和 DCGAN 的原理电媳。以及如何使用 Tensorflow 做一個(gè)簡單的生成圖片的 demo踏揣。
一些后續(xù)閱讀:
Ian Goodfellow 對(duì) GAN 一系列工作總結(jié)的 ppt,確實(shí)精彩匆背,推薦:GAN 之父 NIPS 2016 演講現(xiàn)場直擊:全方位解讀生成對(duì)抗網(wǎng)絡(luò)的原理及未來(http://it.sohu.com/20161210/n475485860.shtml)
GAN 論文匯總呼伸,包含 code:zhangqianhui/AdversarialNetsPapers(https://github.com/zhangqianhui/AdversarialNetsPapers)