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의 극단 영역에서 샘플링을 방지할 수 있습니다.
계산 방법:
- 질량 중심 계산
- 중심에서 주어진 w의 편차를 다음과 같이 조정합니다.
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)을 독립적으로 정규화한다
. 특성 맵의 각 값은 해당 특성 맵의 평균에서 뺀 다음 분산으로 나눕니다.
- ② 학습 가능한 아핀 변환 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)