nvidia StyleGAN 結(jié)構(gòu)詳解
置頂: 原版StyleGAN里有很多自定義參數(shù), 為了方便這里只講述默認(rèn)結(jié)構(gòu)
并且在源碼里有部分地方結(jié)構(gòu)不太人性化, 這里為了更直觀地表達(dá), 會(huì)調(diào)整部分結(jié)構(gòu), 但實(shí)際上與源碼的效果是一致的

相關(guān)操作:
在StyleGAN里(包括判別器), 特征圖的通道數(shù)量與特征圖大小直接掛鉤, 默認(rèn)計(jì)算公式如下:??(注: 特征圖大小必定為2的整數(shù)次方的正方形, 其中nf是通道數(shù), res是特征圖邊長)

并且大量使用一個(gè)叫"blur"的模糊化操作, blur是利用一個(gè)卷積核在每個(gè)通道上做卷積操作, 這不同與平常的卷積, 在所有通道上做卷積操作, 注意blur不影響特征圖的大小, 也就是說需要在特征圖上pad一圈0再卷積

在生成器里有一個(gè)叫上采樣的操作, 它其實(shí)類似與平均池化的反操作, 同理, 另外一個(gè)叫下采樣的操作就是平均池化了

StylaGAN全程使用leaky_relu作為激活函數(shù)act, 但內(nèi)部使用激活函數(shù)的頻率比一般情況要少, 所以激活函數(shù)也會(huì)另外標(biāo)注, leakyReLU計(jì)算:

另外, bias和act也會(huì)單獨(dú)標(biāo)注, 沒寫的就是沒有

StyleGAN里共計(jì)3個(gè)神經(jīng)網(wǎng)絡(luò), G_mapping, G_synthesis和判別器D, 首先先從判別器D開始:
D的結(jié)構(gòu)可以表示為這樣:

其中Block的結(jié)構(gòu)為:

至于中間的MinibatchStddev, 維度變換過于抽象, 這里直接貼代碼吧

其實(shí)就是根據(jù)輸入x生成多一張?zhí)卣鲌D

主生成器G_style:?內(nèi)部有兩個(gè)獨(dú)立的神經(jīng)網(wǎng)絡(luò):?G_mapping和G_synthesis, 外部輸入在G_mapping, 經(jīng)處理后再作為G_synthesis旁路輸入得到圖像輸出, 結(jié)構(gòu)就像官方論文給出那樣

其中G_mapping為簡單的MLP:?(N, 512) 輸入, 經(jīng)過pixel_norm, 再通過8次有bias和act的FC, 輸出(N, 512), pixel_norm計(jì)算如下:?

而在G_synthesis里, 可以分為一個(gè)一個(gè)block, 而block可以分為上半部分和下半部分, 而每部分又可以分為conv和layer_epilogue, 由于兩部分的conv有丶不同, 所以上半部分叫做conv0, 下半部分叫conv1, 其中第一塊block沒有conv0, 并且G_synthesis的輸入為形狀為(N, 512, 4, 4), 全部都是1.0的數(shù)組?
conv0:

conv1就是簡單一個(gè)沒有bias和act的Conv2d
layer_epilogue是StyleGAN的重點(diǎn), 而layer_epilogue又分成2部分, 流程如下:

其中instance_norm是先減去均值再進(jìn)行pixel_norm, 具體表示如下:

Add noise計(jì)算過程如下:? 其中noise是符合正態(tài)分布的隨機(jī)數(shù)組

在寫代碼時(shí)為了避免歧義,?應(yīng)該有: noise.shape=(N,1,H,W), weight.shape=bais.shape=(1,C,1,1), x += noise*weight+bias
StyleMod的另一個(gè)輸入w為G_mapping的輸出,? w經(jīng)過一個(gè)有bias的FC后, 得到長度為2*C的數(shù)組, 而數(shù)組的前半部分作為weight, 后半部分作為bias加入到x里, 流程如下:


結(jié)語: 我至今不知道怎么在tf里搞權(quán)重到np.ndarray