STEP-8:Pytorch-從0實現(xiàn)DCGAN

感謝伯禹學習平臺惹恃,本次學習將記錄記錄如何使用Pytorch高效實現(xiàn)網(wǎng)絡庇茫,熟練掌握Pytorch的基礎知識。記錄不包含理論知識的細節(jié)展開搀菩。

DCGAN

DCGAN呕臂,實在GAN的基礎上,使用卷積網(wǎng)絡替換了原有的G和D中的全連接層肪跋,在圖像生成上具有較好的表現(xiàn)歧蒋。

GAN的結構示意圖
初始準備

使用的輸入圖像的大小為(64,64州既,3)彩色的RGB圖像谜洽。在DCGAN中比較重要的一點是,G生成的圖像大小需要和真實圖片大小保持一致性吴叶,確定G的輸入大小后阐虚,可以設計G的基本結構。

Generator

G的作用是將一個噪聲z使用反卷積的操作蚌卤,將其拉伸到真實數(shù)據(jù)大小实束,反卷積的參數(shù)是可以學習,所以與D的學習參數(shù)迭代造寝,有了對抗磕洪。

import torch
import torchvision
import torch.nn as nn
# G_block,G與之前的網(wǎng)絡設計思想一致诫龙,將復用的模塊封裝為塊
class G_block(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=4,strides=2, padding=1):
        super(G_block,self).__init__()
        self.conv2d_trans=nn.ConvTranspose2d(in_channels, out_channels, kernel_size=kernel_size,
                                             stride=strides, padding=padding, bias=False)
        # 前幾層都是 trans_conv+bn+relu
        self.batch_norm=nn.BatchNorm2d(out_channels,0.8)
        self.activation=nn.ReLU()
    def forward(self,x):
        return self.activation(self.batch_norm(self.conv2d_trans(x)))

如上block中的反卷積輸入大小可以參考如下計算公式析显,在輸入n_k = n_h=16,k_h=k_w=4,p_h=p_w = 1,s_w=s_h=2的情況下輸出大小為(32签赃,32)谷异,也就w,h增大一倍
\begin{aligned} n_h^{'} \times n_w^{'} &= [(n_h k_h - (n_h-1)(k_h-s_h)- 2p_h] \times [(n_w k_w - (n_w-1)(k_w-s_w)- 2p_w]\\ &= [(k_h + s_h (n_h-1)- 2p_h] \times [(k_w + s_w (n_w-1)- 2p_w]\\ &= [(4 + 2 \times (16-1)- 2 \times 1] \times [(4 + 2 \times (16-1)- 2 \times 1]\\ &= 32 \times 32 .\\ \end{aligned}
在G的網(wǎng)絡結構中分尸,它每層的輸出通道數(shù)時遞減的,這點與D剛好有點對稱的意思歹嘹。

class net_G(nn.Module):
    def __init__(self,in_channels):
        super(net_G,self).__init__()

        n_G=64
        self.model=nn.Sequential(
            G_block(in_channels,n_G*8,strides=1,padding=0), 
            G_block(n_G*8,n_G*4),
            G_block(n_G*4,n_G*2),
            G_block(n_G*2,n_G),
            # 最后的輸出卷積層使用的激活函數(shù)為Tanh箩绍,具有較好的泛化能力
            nn.ConvTranspose2d(
                n_G,3,kernel_size=4,stride=2,padding=1,bias=False
            ),
            nn.Tanh()
        )
    def forward(self,x):
        x=self.model(x)
        return x

在給定輸入為(1,1)的噪聲情況下尺上,不難驗證輸出為(64材蛛,64)

Discriminator

D的作用是區(qū)分真假,生成對抗網(wǎng)絡是一個無監(jiān)督學習怎抛,其標簽區(qū)分只有0卑吭,1,分別對應生成數(shù)據(jù)和真實數(shù)據(jù)马绝。D的結構豆赏,類似于G的反過來的意思。

# 定義D的復用塊富稻,使用正常的卷積網(wǎng)絡
class D_block(nn.Module):
    def __init__(self,in_channels,out_channels,kernel_size=4,strides=2,
                 padding=1,alpha=0.2):
        super(D_block,self).__init__()
        self.conv2d=nn.Conv2d(in_channels,out_channels,kernel_size,strides,padding,bias=False)
        # 這里用的時conv+bn+leakyrelu掷邦,論文中給出這樣有利于收斂。
        self.batch_norm=nn.BatchNorm2d(out_channels,0.8)
        self.activation=nn.LeakyReLU(alpha)
    def forward(self,X):
        return self.activation(self.batch_norm(self.conv2d(X)))

對應的D

class net_D(nn.Module):
    def __init__(self,in_channels):
        super(net_D,self).__init__()
        n_D=64
        self.model=nn.Sequential(
            D_block(in_channels,n_D),
            D_block(n_D,n_D*2),
            D_block(n_D*2,n_D*4),
            D_block(n_D*4,n_D*8)
        )
        self.conv=nn.Conv2d(n_D*8,1,kernel_size=4,bias=False)
        # 最后使用的sigmoid激活椭赋,常的分類激活函數(shù)
        self.activation=nn.Sigmoid()
    def forward(self,x):
        x=self.model(x)
        x=self.conv(x)
        x=self.activation(x)
        return x

這里由于D輸入尺寸為為(64抚岗,64)所以其最后的輸出為(1,1)

如何訓練這樣的網(wǎng)絡

在DCGAN中纹份,網(wǎng)絡通常是迭代訓練的苟跪,固定G訓練D,固定D訓練G蔓涧。件已。。
訓練過程中的損失計算參考如下代碼

def update_D(X,Z,net_D,net_G,loss,trainer_D):
    batch_size=X.shape[0]
    Tensor=torch.cuda.FloatTensor
    ones=Variable(Tensor(np.ones(batch_size,)),requires_grad=False).view(batch_size,1)
    zeros = Variable(Tensor(np.zeros(batch_size,)),requires_grad=False).view(batch_size,1)
    #訓練D的時候元暴,給原始圖1標簽篷扩,生成圖0標簽
    real_Y=net_D(X).view(batch_size,-1)
    fake_X=net_G(Z)
    fake_Y=net_D(fake_X).view(batch_size,-1)
    loss_D=(loss(real_Y,ones)+loss(fake_Y,zeros))/2
    loss_D.backward()
    trainer_D.step()
    return float(loss_D.sum())

def update_G(Z,net_D,net_G,loss,trainer_G):
    batch_size=Z.shape[0]
    Tensor=torch.cuda.FloatTensor
    ones=Variable(Tensor(np.ones((batch_size,))),requires_grad=False).view(batch_size,1)
    # 在訓練G的時候我們需要給定生成圖1標簽
    fake_X=net_G(Z)
    fake_Y=net_D(fake_X).view(batch_size,-1)
    loss_G=loss(fake_Y,ones)
    loss_G.backward()
    trainer_G.step()
    return float(loss_G.sum())

讀取數(shù)據(jù)訓練參考如下

    for epo in range(epochs):
        for data in dataiter:
            z = ..
            d.zero_grad()
            update_D(...)
            g.zero_grad()
            update_G

總結

DCGAN 可以說是入門GAN的開始,后面有很多基于GAN思路的改進茉盏,本質上來說鉴未,GAN的思路使得神經(jīng)網(wǎng)絡具有了可控的創(chuàng)造性,但距離人的差距還是很大鸠姨。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末铜秆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子讶迁,更是在濱河造成了極大的恐慌连茧,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啸驯,居然都是意外死亡客扎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門罚斗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來徙鱼,“玉大人,你說我怎么就攤上這事针姿「み海” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵搓幌,是天一觀的道長杆故。 經(jīng)常有香客問我,道長溉愁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任饲趋,我火速辦了婚禮拐揭,結果婚禮上,老公的妹妹穿的比我還像新娘奕塑。我一直安慰自己堂污,他們只是感情好,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布龄砰。 她就那樣靜靜地躺著盟猖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪换棚。 梳的紋絲不亂的頭發(fā)上式镐,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音固蚤,去河邊找鬼娘汞。 笑死,一個胖子當著我的面吹牛夕玩,可吹牛的內容都是我干的你弦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼燎孟,長吁一口氣:“原來是場噩夢啊……” “哼禽作!你這毒婦竟也來了?” 一聲冷哼從身側響起揩页,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤旷偿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狸捅,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡衷蜓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了尘喝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磁浇。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖朽褪,靈堂內的尸體忽然破棺而出置吓,到底是詐尸還是另有隱情,我是刑警寧澤缔赠,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布衍锚,位于F島的核電站,受9級特大地震影響嗤堰,放射性物質發(fā)生泄漏戴质。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一踢匣、第九天 我趴在偏房一處隱蔽的房頂上張望告匠。 院中可真熱鬧,春花似錦离唬、人聲如沸后专。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戚哎。三九已至,卻和暖如春嫂用,著一層夾襖步出監(jiān)牢的瞬間型凳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工尸折, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啰脚,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓实夹,卻偏偏與公主長得像橄浓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子亮航,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內容