生成對(duì)抗網(wǎng)絡(luò)(GANs,https://en.wikipedia.org/wiki/Generative_adversarial_network)是一類(lèi)具有基于網(wǎng)絡(luò)本身即可以生成數(shù)據(jù)能力的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。由于GANs的強(qiáng)大能力,在深度學(xué)習(xí)領(lǐng)域里對(duì)它們的研究是一個(gè)非常熱門(mén)的話題。在過(guò)去很短的幾年里,它們已經(jīng)從產(chǎn)生模糊數(shù)字成長(zhǎng)到創(chuàng)造如真實(shí)人像般逼真的圖像。
?1?? GAN的工作方式
GANs屬于生成模型的一類(lèi)。這意味著它們能夠產(chǎn)生,或者說(shuō)是生成完全新的“有效”數(shù)據(jù)。有效數(shù)據(jù)是指網(wǎng)絡(luò)的輸出結(jié)果應(yīng)該是我們認(rèn)為可以接受的目標(biāo)。
舉例說(shuō)明,舉一個(gè)我們希望為訓(xùn)練一個(gè)圖像分類(lèi)網(wǎng)絡(luò)生成一些新圖像的例子。當(dāng)然對(duì)于這樣的應(yīng)用來(lái)說(shuō),我們希望訓(xùn)練圖像越真實(shí)越好,可能在風(fēng)格上與其他圖像分類(lèi)訓(xùn)練數(shù)據(jù)非常相似。
為了做到這些,GANs是以?xún)蓚€(gè)獨(dú)立的對(duì)抗網(wǎng)絡(luò)組成:生成器和判別器。當(dāng)僅將嘈雜的圖像陣列作為輸入時(shí),會(huì)對(duì)生成器進(jìn)行訓(xùn)練以創(chuàng)建逼真的圖像。判別器經(jīng)過(guò)訓(xùn)練可以對(duì)圖像是否真實(shí)進(jìn)行分類(lèi)。
GANs真正的能力來(lái)源于它們遵循的對(duì)抗訓(xùn)練模式。生成器的權(quán)重是基于判別器的損失所學(xué)習(xí)到的。因此,生成器被它生成的圖像所推動(dòng)著進(jìn)行訓(xùn)練,很難知道生成的圖像是真的還是假的。同時(shí),生成的圖像看起來(lái)越來(lái)越真實(shí),判別器在分辨圖像真實(shí)與否的能力變得越來(lái)越強(qiáng),無(wú)論圖像用肉眼看起來(lái)多么的相似。
從技術(shù)的角度來(lái)看,判別器的損失即是分類(lèi)圖像是真是假的錯(cuò)誤值;我們正在測(cè)量它區(qū)分真假圖像的能力。生成器的損失將取決于它在用假圖像“愚弄”判別器的能力,即判別器僅對(duì)假圖像的分類(lèi)錯(cuò)誤,因?yàn)樯善飨M撝翟礁咴胶谩?/p>
因此,GANs建立了一種反饋回路,其中生成器幫助訓(xùn)練判別器,而判別器又幫助訓(xùn)練生成器。它們同時(shí)變得更強(qiáng)。下面的圖表有助于說(shuō)明這一點(diǎn)。?
生成對(duì)抗網(wǎng)絡(luò)的結(jié)構(gòu)說(shuō)明
?2???在PyTorch中訓(xùn)練GAN來(lái)生成數(shù)字
現(xiàn)在我們將通過(guò)一個(gè)例子來(lái)展示如何使用PyTorch建立和訓(xùn)練我們自己的GAN!MNIST數(shù)據(jù)集包含60000個(gè)訓(xùn)練數(shù)據(jù),數(shù)據(jù)是像素尺寸28x28的1-9的黑白數(shù)字圖片。這個(gè)數(shù)據(jù)集非常適合我們的用例,同時(shí)也是非常普遍的用于機(jī)器學(xué)習(xí)的概念驗(yàn)證以及一個(gè)非常完備的集合。
我們將從?import?開(kāi)始,所需的僅僅是PyTorch中的東西。
import torch from torch import nn, optim from torch.autograd.variable import Variable import torchvision import torchvision.transforms as transforms
接下來(lái),我們?yōu)橛?xùn)練數(shù)據(jù)準(zhǔn)備DataLoader。請(qǐng)記住,我們想要的是為MNIST生成隨機(jī)數(shù)字,即從0到9。因此,我也將需要為這10個(gè)數(shù)字建立標(biāo)簽。
現(xiàn)在我們可以開(kāi)始建立網(wǎng)絡(luò)了,從下面的Discriminator(判別器)網(wǎng)絡(luò)開(kāi)始,回想一下,判別器網(wǎng)絡(luò)是對(duì)圖像真實(shí)與否進(jìn)行分類(lèi)——它是一個(gè)圖像分類(lèi)網(wǎng)絡(luò)。因此,我們的輸入是符合標(biāo)準(zhǔn)MNIST大小的圖像:28x28像素。我們把這張圖像展平成一個(gè)長(zhǎng)度為784的向量。輸出是一個(gè)單獨(dú)的值,表示圖像是否是實(shí)際的MNIST數(shù)字。
接下來(lái)到了生成器部分。生成器網(wǎng)絡(luò)負(fù)責(zé)創(chuàng)建實(shí)際的圖像——它可以從一個(gè)純?cè)肼暤妮斎胱龅竭@一點(diǎn)!在這個(gè)例子中,我們要讓生成器從一個(gè)長(zhǎng)度為100的向量開(kāi)始——注意:這只是純隨機(jī)噪聲。從這個(gè)向量,我們的生成器將輸出一個(gè)長(zhǎng)度為784的向量,稍后我們可以將其重塑為標(biāo)準(zhǔn)MNIST的28x28像素。
為了建立訓(xùn)練過(guò)程,我們將需要做以下工作:
1 . 損失函數(shù)
2 . 每個(gè)網(wǎng)絡(luò)的優(yōu)化器
3 . 訓(xùn)練次數(shù)
4 . batch數(shù)量
如果我們希望網(wǎng)絡(luò)在GPU上執(zhí)行,PyTorch要求我們必須明確地把模型移動(dòng)到GPU上。這部分所有的代碼如下所示。
現(xiàn)在開(kāi)始訓(xùn)練循環(huán)。PyTorch中的訓(xùn)練循環(huán)通常由一個(gè)遍歷各個(gè)訓(xùn)練周期的外部循環(huán)和一個(gè)遍歷batch數(shù)據(jù)的內(nèi)部循環(huán)組成。訓(xùn)練GAN的關(guān)鍵是我們需要在一個(gè)循環(huán)中更新生成器和判別器。查看下面的代碼來(lái)訓(xùn)練GAN和PyTorch。這些步驟在代碼下面有更詳細(xì)的描述。
(1)我們首先為判別器準(zhǔn)備 *real* 圖像數(shù)據(jù)。輸入的是一批真實(shí)的MNIST圖像。輸出全為1的向量,因?yàn)?表示圖像是真實(shí)的。
(2)接下來(lái),我們將為生成器準(zhǔn)備輸入向量以便生成假圖像。回想一下,我們的生成器網(wǎng)絡(luò)采用長(zhǎng)度為100的輸入向量,這就是我們?cè)谶@里所創(chuàng)建的向量。images.size(0)用于批處理大小。
(3)通過(guò)從步驟(2)中創(chuàng)建的隨機(jī)噪聲數(shù)據(jù)向量,我們可以繞過(guò)這個(gè)向量到生成器來(lái)生成假的圖像數(shù)據(jù)。這將結(jié)合我們從步驟1的實(shí)際數(shù)據(jù)來(lái)訓(xùn)練判別器。請(qǐng)注意,這次我們的標(biāo)簽向量全為0,因?yàn)?代表假圖像的類(lèi)標(biāo)簽。
(4)通過(guò)假的和真的圖像以及它們的標(biāo)簽,我們可以訓(xùn)練我們的判別器進(jìn)行分類(lèi)。總損失將是假圖像的損失+真圖像的損失。
(5)現(xiàn)在我們的判別器已經(jīng)更新,我們可以用它來(lái)進(jìn)行預(yù)測(cè)。這些預(yù)測(cè)的損失將通過(guò)生成器反向傳播,這樣生成器的權(quán)重將根據(jù)它欺騙判別器的程度進(jìn)行具體更新
(5a)生成一些假圖像進(jìn)行預(yù)測(cè)
(5b)使用判別器對(duì)假圖像進(jìn)行分批次預(yù)測(cè)并保存輸出。
(6)使用判別器的預(yù)測(cè)訓(xùn)練生成器。注意,我們使用全為1的 _real_labels_ 作為目標(biāo),因?yàn)槲覀兊纳善鞯哪繕?biāo)是創(chuàng)建看起來(lái)真實(shí)的圖像并且預(yù)測(cè)為1!因此,生成器的損失為0將意味著判別器預(yù)測(cè)全為1.
瞧,這就是我們訓(xùn)練GAN生成MNIST圖像的全部代碼!只需要安裝PyTorch即可運(yùn)行。下面的gif就是經(jīng)過(guò)超過(guò)40個(gè)訓(xùn)練周期生成的圖像。
審核編輯:黃飛
?
評(píng)論