[GAN] [論文ノート] 敵対的生成ネットワークのためのスタイルベースのジェネレーター アーキテクチャ

1. 論文制作

論文制作については、「StyleGAN-Style-based Generative Adversarial Network」を参照してください。

2.コード

コードリファレンスstyleGAN.py - facebookresearch/pytorch_GAN_zoo - GitHub1s

Trainer の簡単な構造は次のとおりです (一部省略)。

2.1 ネットワークのマッピング

2.1.1 ネットワーク構造

8 つの MLP で構成され、出力 w は入力 z と同じサイズ (512×1)

class MappingLayer(nn.Module):
#dimInput:512 dimLatent:512 nLayers:8
    def __init__(self, dimIn, dimLatent, nLayers, leakyReluLeak=0.2):
        super(MappingLayer, self).__init__()
        self.FC = nn.ModuleList()

        inDim = dimIn
        for i in range(nLayers):
            self.FC.append(EqualizedLinear(inDim, dimLatent, lrMul=0.01, equalized=True, initBiasToZero=True))
            inDim = dimLatent

        self.activation = torch.nn.LeakyReLU(leakyReluLeak)

    def forward(self, x):
        for layer in self.FC:
            x = self.activation(layer(x))

2.1.2 マッピング ネットワークへの入力

    def buildNoiseData(self, n_samples, inputLabels=None):
        inputLatent = torch.randn(
            n_samples, self.config.noiseVectorDim).to(self.device)
        return inputLatent, None
    #根据噪声维度生成随机输入


    inputLatent, targetRandCat = self.buildNoiseData(n_samples)

2.1.3 切り捨て手法

切り捨て技術を使用すると、W の極端な領域からのサンプリングが回避されます。

計算方法:

  1. 重心の計算
  2. 指定された w の中心からの偏差を次のようにスケールします。w' =\overline{ w} +\psi \left ( w-\overline{w} \right )
        if self.training:
            self.mean_w = self.gamma_avg * self.mean_w + (1-self.gamma_avg) * mapping.mean(dim=0, keepdim=True)

        if self.phiTruncation < 1:#0.999
            mapping = self.mean_w + self.phiTruncation * (mapping - self.mean_w)

2.2 セクション

(ただし、AdaIN では「水滴」問題が発生することが StyleGAN2 で判明しました)

  • ①まず、各特徴マップ xi (特徴マップ) を独立に正規化します\frac{\left ( x_i - \mu (x_i ) \right )}{\sigma(x)) }特徴マップ内の各値は、その特徴マップの平均から減算され、分散で除算されます。
  • ②学習可能なアフィン変換 A (全結合層) は、w をスタイル = (ys,i,yb,i) の AdaIN の変換とスケーリング係数 y に変換します。
  • ③ 次に、スタイルで学習した変換係数とスケーリング係数を使用して、各特徴マップ上でスケールと変換変換を実行します。
class AdaIN(nn.Module):

    def __init__(self, dimIn, dimOut, epsilon=1e-8):
        super(AdaIN, self).__init__()
        self.epsilon = epsilon
        self.styleModulator = EqualizedLinear(dimIn, 2*dimOut, equalized=True,
                                              initBiasToZero=True)
        self.dimOut = dimOut

    def forward(self, x, y):

        # x: N x C x W x H
        batchSize, nChannel, width, height = x.size()
        tmpX = x.view(batchSize, nChannel, -1)
        mux = tmpX.mean(dim=2).view(batchSize, nChannel, 1, 1)
        varx = torch.clamp((tmpX*tmpX).mean(dim=2).view(batchSize, nChannel, 1, 1) - mux*mux, min=0)
        varx = torch.rsqrt(varx + self.epsilon)
        x = (x - mux) * varx

        # Adapt style
        styleY = self.styleModulator(y)
        yA = styleY[:, : self.dimOut].view(batchSize, self.dimOut, 1, 1)
        yB = styleY[:, self.dimOut:].view(batchSize, self.dimOut, 1, 1)

        return yA * x + yB

2.3 合成ネットワーク

2.3.1 入力定数

ランダムに生成された学習可能なパラメータが初期量として入力されます

self.baseScale0 = nn.Parameter(torch.ones(1, dimMapping, 4, 4), requires_grad=True)

2.3.2 ランダムな変更

 StyleGAN のアーキテクチャは、各畳み込みの後にノイズを追加することにより、空間内でランダムな (詳細な) 変化を伴う画像を生成します。

            noiseMod = self.noiseModulators[nLayer]
            feature = Upscale2d(feature)
                        #卷积
            feature = group[0](feature) + noiseMod[0](torch.randn((batchSize, 1,
                                                      feature.size(2),
                                                      feature.size(3)), device=x.device))
            feature = self.activation(feature)
                       #AdaIN
            feature = group[1](feature, mapping)
                        #卷积
            feature = group[2](feature) + noiseMod[1](torch.randn((batchSize, 1,
                                                      feature.size(2),
                                                      feature.size(3)), device=x.device))
            feature = self.activation(feature)
                        #AdaIN
            feature = group[3](feature, mapping)

2.3.3 ノイズの発生

class NoiseMultiplier(nn.Module):

    def __init__(self):
        super(NoiseMultiplier, self).__init__()
        self.module = nn.Conv2d(1, 1, 1, bias=False)
        self.module.weight.data.fill_(0)

    def forward(self, x):

        return self.module(x)

おすすめ

転載: blog.csdn.net/weixin_50862344/article/details/131588020