對PatchGAN的感知域(receptive_field)理解


for basic discriminator of GANs

判別器用於感知生成器產生的合成圖片和ground-truth的差異,並旨在實現區分出fake or real;

同時,判別器的輸出也是經過一系列的conv后得到的一個標量值,一般使這個值激活在0~1之間;

但是,這樣的結果存在着一些問題:

  1.輸出的結果顯然是一個整體圖片的加權值,無法體現局部圖像的特征,對於精度要求高的的圖像遷移等任務比較困難。

for Patch-based discriminator of GANs

PatchGAN的思路是最后的輸出不是一個標量值,而是一個$N*N$的矩陣$X$,其實$X_{ij}$表示patch $ij$是fake or real. 

關鍵點就是:在$X$上的一個神經元$X_{ij}$可以表示一塊輸入patch,這個神經元就對這塊patch的像素敏感,這塊patch 就是 輸出$X_{ij}$的感知域(receptive field).

 

1.這樣方法 通過每個patch 進行差別的判別, 實現了局部圖像特征的提取和表征, 有利於實現更為高分辨率的圖像生產;同時, 對最后的 分類特征圖進行平均后, 也能夠實現相比

2.單標量輸出的更為精確的整體差異表示,相當於對整體進行加權求和平均,對於某些特征差異大的局部圖像特征, 能夠實現比basic D 更為合理的 損失表示。

3.這種機制,將局部圖像特征和整體圖像特性相融合。

Mathematical:

有個解決辦法就是將圖像裁剪成多個重疊的patches,分別進行判別器的差異識別,並對得到的結果進行平均,但是這樣存在大的運算消耗。

Obviously,卷積神經網絡的強大之處在於,它們能以相同的方式獨立地處理每個圖像塊,所以在最后的實際過程中,得到的輸出矩陣的每一神經元相當於就是在執行每個patch的單獨判斷的結果,這樣的結果具有高效的運算效果。

The size of receptive field:

堆疊不同層的convnets, 最后輸出矩陣的單個神經元的表征的感知域的大小顯然不一樣;感知域越大,這意味着它應該學習距離更遠的對象之間的關系

empirical, 層數越深, 能夠感知的patch的尺寸也越大,但是這樣會付出更多的計算成本和時間消耗,所以需要通過traceback:

function receptive_field_sizes()


% compute input size from a given output size
f = @(output_size, ksize, stride) (output_size - 1) * stride + ksize;


%% n=1 discriminator

% fix the output size to 1 and derive the receptive field in the input
out = ...
f(f(f(1, 4, 1), ...   % conv2 -> conv3
             4, 1), ...   % conv1 -> conv2
             4, 2);       % input -> conv1

fprintf('n=1 discriminator receptive field size: %d\n', out);


%% n=2 discriminator

% fix the output size to 1 and derive the receptive field in the input
out = ...
f(f(f(f(1, 4, 1), ...   % conv3 -> conv4
             4, 1), ...   % conv2 -> conv3
             4, 2), ...   % conv1 -> conv2
             4, 2);       % input -> conv1

fprintf('n=2 discriminator receptive field size: %d\n', out);


%% n=3 discriminator

% fix the output size to 1 and derive the receptive field in the input
out = ...
f(f(f(f(f(1, 4, 1), ...   % conv4 -> conv5
             4, 1), ...   % conv3 -> conv4
             4, 2), ...   % conv2 -> conv3
             4, 2), ...   % conv1 -> conv2
             4, 2);       % input -> conv1

fprintf('n=3 discriminator receptive field size: %d\n', out);


%% n=4 discriminator

% fix the output size to 1 and derive the receptive field in the input
out = ...
f(f(f(f(f(f(1, 4, 1), ...   % conv5 -> conv6
             4, 1), ...   % conv4 -> conv5
             4, 2), ...   % conv3 -> conv4
             4, 2), ...   % conv2 -> conv3
             4, 2), ...   % conv1 -> conv2
             4, 2);       % input -> conv1

fprintf('n=4 discriminator receptive field size: %d\n', out);


%% n=5 discriminator

% fix the output size to 1 and derive the receptive field in the input
out = ...
f(f(f(f(f(f(f(1, 4, 1), ...   % conv6 -> conv7
             4, 1), ...   % conv5 -> conv6
             4, 2), ...   % conv4 -> conv5
             4, 2), ...   % conv3 -> conv4
             4, 2), ...   % conv2 -> conv3
             4, 2), ...   % conv1 -> conv2
             4, 2);       % input -> conv1

fprintf('n=5 discriminator receptive field size: %d\n', out);

實際模型搭建

顯然,是需要堆積多個convnets即可實現PatchGAN的判別器, PatchGAN更多的將它理解為一種機制mechanism,其實整個模型就是一個FCN結構

對於不同的感知域,肯定在D中表征為有不同的convnet層, torch:

function defineD_n_layers(input_nc, output_nc, ndf, n_layers)
    if n_layers==0 then
        return defineD_pixelGAN(input_nc, output_nc, ndf)
    else
    
        local netD = nn.Sequential()
        
        -- input is (nc) x 256 x 256
        netD:add(nn.SpatialConvolution(input_nc+output_nc, ndf, 4, 4, 2, 2, 1, 1))
        
        module = nn.SpatialConvolution(nInputPlane, nOutputPlane, kW, kH, [dW], [dH], [padW], [padH])
        
        netD:add(nn.LeakyReLU(0.2, true))
        
        local nf_mult = 1
        local nf_mult_prev = 1   
        for n = 1, n_layers-1 do 
            nf_mult_prev = nf_mult
            nf_mult = math.min(2^n,8)
            netD:add(nn.SpatialConvolution(ndf * nf_mult_prev, ndf * nf_mult, 4, 4, 2, 2, 1, 1))
            netD:add(nn.SpatialBatchNormalization(ndf * nf_mult)):add(nn.LeakyReLU(0.2, true))
        end
        
        -- state size: (ndf*M) x N x N
        nf_mult_prev = nf_mult
        nf_mult = math.min(2^n_layers,8)
        netD:add(nn.SpatialConvolution(ndf * nf_mult_prev, ndf * nf_mult, 4, 4, 1, 1, 1, 1))
        netD:add(nn.SpatialBatchNormalization(ndf * nf_mult)):add(nn.LeakyReLU(0.2, true))
        -- state size: (ndf*M*2) x (N-1) x (N-1)
        netD:add(nn.SpatialConvolution(ndf * nf_mult, 1, 4, 4, 1, 1, 1, 1))
        -- state size: 1 x (N-2) x (N-2)
        
        netD:add(nn.Sigmoid())
        -- state size: 1 x (N-2) x (N-2)
        
        return netD
    end
end9

 

一些思考 future works

1.PatchGAN的整個機制的核心在於對 G網絡結果的優化,優化了類似U-net的結構(encoder-decoder的架構),使得低階信息跨越bottleneck,讓更多的低階信息得以交換,

並讓G的訓練有如同  Res-block般的平緩梯度,一定程度上減緩了梯度消失, 我們知道Resnet較為好的解決了多層convnet堆疊后的訓練困難的問題,其類似於放大器的結構,讓訓練

更為的有效。

 

2.由於patches的重疊性和局部特征性,對於不同的任務, patches之間的局部特征的相關性肯定存在差異, 所以對於感知域的尺寸確定需要有差異性和動態性,才能實現較為好的性能。

 

3.對於G 來說, 其解碼過程其實使用的是微步幅卷積操作或叫做反卷積操作,但是反卷積操作其實對於圖像的產生是存在着爭議性的,改善和提高這個部分,具有一點的前景, 可以采用

多個的feature map進行重疊作為輸入的操作, 得到一個多層特征圖, 嘗試直接使用一個下采樣卷積作為一個生成器。

 

4.對於CGANs 機制的引入, 其實是使得 GAN的訓練更加穩定, 進行有約束的執行generative 任務, 進行加 buff的 判別的任務。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM