[GAN] [논문 노트] 생성적 적대 신경망을 위한 스타일 기반 생성기 아키텍처

1. 논문작업

논문 작업은 [ StyleGAN 스타일 기반 생성적 적대 신경망 ]을 참고하세요.

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에서 발견되었지만)

  • ①먼저, 각 특징맵(feature map) xi(feature map)을 독립적으로 정규화한다 \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