Styleගන්2

මෙය PyTorch කඩදාසි ක්රියාත්මක කිරීමකි StyleGan 2හඳුන්වා දෙන StyleGan හි රූපයේ ගුණාත්මකභාවය විශ්ලේෂණය කිරීම සහ වැඩි දියුණු කිරීම . StyleGan 2 යනු වැඩි දියුණු කිරීමකි StyleGan කඩදාසි වලින් උත්පාදක අහිතකර ජාල සඳහා ශෛලිය මත පදනම් වූ උත්පාදක ගෘහ නිර්මාණ ශිල්පය. සහ StyleGan පදනම් වී ඇත්තේ කඩදාසි වලින් ප්රගතිශීලී GAN මත ය වැඩි දියුණු කළ ගුණාත්මකභාවය, ස්ථායිතාව සහ විචලනය සඳහා GANs ප්රගතිශීලී වර්ධනය. මෙම පත්රිකා තුනම NVIDIA AIවෙතින් එකම කතුවරුන්ගෙන් වේ.

අපගේක්රියාත්මක කිරීම අවම වේ StyleGAN 2 ආදර්ශ පුහුණු කේතය. ක්රියාත්මක කිරීම සරල ලෙස තබා ගැනීම සඳහා සහාය වන්නේ තනි GPU පුහුණුවක් පමණි. පුහුණු ලූපය ඇතුළුව කේත පේළි 500 කට වඩා අඩු මට්ටමක තබා ගැනීම සඳහා එය හැකිලීමට අපට හැකි විය.

🏃මෙන්න පුහුණු කේතය: experiment.py .

Generated Images

මේවා80K පියවර සඳහා පුහුණුවෙන් පසු ජනනය කරන ලද රූප වේ.

අපිමුලින්ම උසස් මට්ටමේ ප්රශ්න පත්ර තුන හඳුන්වා දෙන්නෙමු.

උත්පාදකඅහිතකර ජාල

උත්පාදකඅහිතකර ජාලයන් සංරචක දෙකක් ඇත; උත්පාදක යන්ත්රය සහ වෙනස්කම් කරන්නා. උත්පාදක ජාලය අහඹු ගුප්ත දෛශිකයක් () ගෙන යථාර්ථවාදී රූපයක් ජනනය කිරීමට උත්සාහ කරයි. වෙනස්කම් කිරීමේ ජාලය සැබෑ රූප ජනනය කරන ලද රූප වලින් වෙන්කර හඳුනා ගැනීමට උත්සාහ කරයි. අපි ජාල දෙක එකට පුහුණු කරන විට උත්පාදක යන්ත්රය සැබෑ රූප වලින් වෙන් කොට හඳුනාගත නොහැකි රූප ජනනය කිරීමට පටන් ගනී.

ප්රගතිශීලීGAN

ප්රගතිශීලීGAN ප්රමාණයෙන් ඉහළ විභේදන රූප () ජනනය කරයි. එය එසේ කරන්නේ රූපයේ ප්රමාණය ක්රමයෙන් වැඩි කිරීමෙනි. පළමුව, එය රූපයක් නිපදවන ජාලයක් පුහුණු කරයි , පසුව රූපයක්, සහ යනාදිය අපේක්ෂිත රූප විභේදනය දක්වා.

සෑමවිභේදනයකදීම, උත්පාදක ජාලය මඟින් ප්රතිරූපයක් නිපදවයි ගුප්ත අවකාශයේ එය RGB බවට පරිවර්තනය වේ. අපි අඩු විභේදනයක සිට ඉහළ විභේදනයක් දක්වා ඉදිරියට යන විට (සිට කියන්න ) අපි ගුප්ත රූපය පරිමාණය කර නව බ්ලොක් එකක් එකතු කරමු (දෙකක් කැටි ගැසුණු ස්ථර) සහ RGB ලබා ගැනීම සඳහා නව තට්ටුවක්. පරිමාණය කරන ලද RGB රූපයට අවශේෂ සම්බන්ධතාවයක් එක් කිරීමෙන් සංක්රාන්තිය සුමටව සිදු කෙරේ. නව කොටස භාර ගැනීමට ඉඩ දීම සඳහා මෙම අවශේෂ සම්බන්ධතාවයේ බර සෙමෙන් අඩු වේ.

වෙනස්කම්කරන්නා යනු උත්පාදක ජාලයේ දර්පණ පිළිබිඹුවක් වේ. වෙනස්කම් කරන්නාගේ ප්රගතිශීලී වර්ධනය ද ඒ හා සමානව සිදු කෙරේ.

progressive_gan.svg

සහ විශේෂාංග සිතියම් විභේදන පරිමාණය සහ පරිමාණය දක්වයි. , ,... උත්පාදක යන්ත්රයේ හෝ වෙනස්කම් කිරීමේ කොටසෙහි විශේෂාංග සිතියම් විභේදනය දක්වයි. සෑම වෙනස්කම් කරන්නෙකු සහ උත්පාදක බ්ලොක් එකක් කාන්දු වන RelU සක්රිය කිරීම් සහිත කැටි ගැසුණු ස්ථර 2 කින් සමන්විත වේ.

ක්රියාත්මකකිරීමේදී අප පහත සාකච්ඡා කළ විචලනය සහ සමාන ඉගෙනුම් අනුපාතය වැඩි කිරීම සඳහා ඔවුන් මිනිබැච් සම්මත අපගමනය භාවිතා කරයි. ඔවුන් පික්සල් අනුව සාමාන්යකරණය භාවිතා කරන අතර එහිදී සෑම පික්සෙල් එකකම විශේෂාංග දෛශිකය සාමාන්යකරණය වේ. ඔවුන් සියලු කැටි ගැසුණු ස්ථර ප්රතිදානයන් සඳහා මෙය අදාළ වේ (RGB හැර).

Styleගන්

StyleGANහි උත්පාදක යන්ත්රය වැඩි දියුණු කරයි ප්රගතිශීලී GAN වෙනස්කම් කරන ගෘහ නිර්මාණ ශිල්පය එලෙසම තබා ගනී.

ජාලසිතියම්කරණය

එයඅහඹු ගුප්ත දෛශිකය () වෙනස් ගුප්ත අවකාශයකට () සිතියම් ගත කරයි, ස්ථර 8 ක ස්නායුක ජාලයක් ඇත. මෙය විචලනයන්ගේ සාධක වඩාත් රේඛීය (disentangled) වන අතරමැදි ගුප්ත අවකාශයක් ලබා දෙයි.

ඒඩින්

එවිට එක් ස්ථරයකට දෛශික (ශෛලීන්) දෙකකට පරිවර්තනය වන අතර , එක් එක් ස්ථරයේ පරිමාණය හා මාරුවීම (පක්ෂග්රාහී වීම) සඳහා භාවිතා වේ ක්රියාකරු (සාමාන්යකරණය සහ පරිමාණය):

ශෛලියමිශ්ර

උත්පාදකයන්ත්රය යාබද මෝස්තර සහසම්බන්ධිත යැයි උපකල්පනය කිරීම වැළැක්වීම සඳහා, ඔවුන් අහඹු ලෙස විවිධ බ්ලොක් සඳහා විවිධ මෝස්තර භාවිතා කරයි. එනම්, ඒවා ගුප්ත දෛශික දෙකක් සහ අනුරූප නියැදි කර සමහර බ්ලොක් සඳහා පදනම් වූ මෝස්තර සහ සමහරක් සඳහා පදනම් වූ මෝස්තර භාවිතා කරයි අහඹු ලෙස කළු පැහැයක් ගනී.

ස්ථිතිකවිචලනය

සෑමබ්ලොක් එකකටම ශබ්දය ලබා දී ඇති අතර එමඟින් උත්පාදක යන්ත්රය වඩාත් යථාර්ථවාදී රූප නිර්මාණය කිරීමට උපකාරී වේ. උගත් බරකින් එක් නාලිකාවකට ශබ්දය පරිමාණය වේ.

ද්විභාෂාඉහළ සහ පහළ නියැදීම්

සියලුමඉහළ සහ පහළ නියැදි මෙහෙයුම් ද්විතියර් සුමටනය සමඟ ඇත.

style_gan.svg

රේඛීය ස්ථරයක් දක්වයි. විකාශන හා පරිමාණ මෙහෙයුමක් දක්වයි (ශබ්දය තනි නාලිකාවකි). StyleGan ප්රගතිශීලී GAN වැනි ප්රගතිශීලී වර්ධනය ද භාවිතා කරයි.

Styleගන්2

StyleGan2 උත්පාදක යන්ත්රය සහ වෙනස්කම් කරන්නා යන දෙකම වෙනස් කරයි StyleGan.

බරමොඩියුලේෂන් සහ ඩිමොඩියුලේෂන්

ඔවුන් ක්රියාකරු ඉවත් කර බර මොඩියුලේෂන් සහ ඩිමොඩියුලේෂන් පියවරෙන් එය ප්රතිස්ථාපනය කරයි. මෙමඟින් ජනනය කරන ලද රූපවල ඇති ජල බිඳිති කෞතුක වස්තු ලෙස ඔවුන් හඳුන්වන දේ වැඩි දියුණු කළ යුතු අතර ඒවා ක්රියාකරු තුළ සාමාන්යකරණය වීම නිසා ඇතිවේ. ස්ථරයකට ශෛලීය දෛශිකය ගණනය කරනු ලැබේ .

එවිටකැටි ගැසුණු බර පහත පරිදි මොඩියුලේට් වේ. ( මෙහි දී අතරමැදි ගුප්ත අවකාශය නොවන පඩි අදහස්, අපි කඩදාසි ලෙස එම අංකනය දැඩිව බැඳී සිටින.)

එවිට එය සාමාන්යකරණය කිරීමෙන් ඉවත් කරනු ලැබේ, ආදාන නාලිකාව කොතැනද, ප්රතිදාන නාලිකාව වන අතර යනු කර්නල් දර්ශකයයි.

මාර්ගයදිග විධිමත්

මාර්ගදිග නියාමනය මඟින් ජනනය කරන ලද රූපයේ ශුන්ය නොවන, ස්ථාවර ප්රමාණයේ වෙනසක් ඇති කිරීම සඳහා ස්ථාවර ප්රමාණයේ පියවරක් දිරිමත් කරයි.

ප්රගතිශීලීවර්ධනයක් නැත

StyleGan2වෙනස්කම් කරන්නා තුළ අවශේෂ සම්බන්ධතා (පහළට නියැදීම සමඟ) භාවිතා කරන අතර උත්පාදක යන්ත්රයේ ඉහළ නියැදීම් සමඟ සම්බන්ධතා මඟ හරින්න (එක් එක් ස්ථරයෙන් RGB ප්රතිදානයන් එකතු කරනු ලැබේ - විශේෂාංග සිතියම්වල අවශේෂ සම්බන්ධතා නොමැත). පුහුණුව ආරම්භයේ දී අඩු විභේදන ස්ථරවල දායකත්වය ඉහළ මට්ටමක පවතින බවත් පසුව අධි-විභේදන ස්ථර භාර ගන්නා බවත් අත්හදා බැලීම් සමඟ ඔවුන් පෙන්වා දෙයි.

148import math
149from typing import Tuple, Optional, List
150
151import numpy as np
152import torch
153import torch.nn.functional as F
154import torch.utils.data
155from torch import nn

ජාලසිතියම්කරණය

Mapping Network

මෙයරේඛීය ස්ථර 8 ක් සහිත MLP වේ. සිතියම්කරණ ජාලය ගුප්ත දෛශිකය අතරමැදි ගුප්ත අවකාශයකට සිතියම් ගත කරයි. විචල්යතාවයේ සාධක වඩාත් රේඛීය වන රූප අවකාශයෙන් අවකාශය විසුරුවා හරිනු ඇත.

158class MappingNetwork(nn.Module):
  • features යනු විශේෂාංග ගණන සහ
  • n_layers සිතියම්කරණ ජාලයේ ස්ථර ගණන වේ.
173    def __init__(self, features: int, n_layers: int):
178        super().__init__()

MLPසාදන්න

181        layers = []
182        for i in range(n_layers):
184            layers.append(EqualizedLinear(features, features))

කාන්දුවන රිලේ

186            layers.append(nn.LeakyReLU(negative_slope=0.2, inplace=True))
187
188        self.net = nn.Sequential(*layers)
190    def forward(self, z: torch.Tensor):

සාමාන්‍යකරන්න

192        z = F.normalize(z, dim=1)

සිතියම

194        return self.net(z)

StyleGan2උත්පාදක යන්ත්රය

Generator

රේඛීය ස්ථරයක් දක්වයි. විකාශන හා පරිමාණ මෙහෙයුමක් දක්වයි (ශබ්දය තනි නාලිකාවකි). toRGB ශෛලීය මොඩියුලේෂන් එකක් ද ඇති අතර එය සරල ලෙස තබා ගැනීම සඳහා රූප සටහනේ පෙන්වා නැත.

උත්පාදකයන්ත්රය ඉගෙන ගත් නියතයකින් ආරම්භ වේ. එවිට එය කුට්ටි මාලාවක් ඇත. විශේෂාංග සිතියම් විභේදනය සෑම බ්ලොක් එකකම දෙගුණ වේ සෑම බ්ලොක් එකක්ම RGB රූපයක් ප්රතිදානය කරන අතර අවසාන RGB රූපය ලබා ගැනීම සඳහා ඒවා පරිමාණය කර සාරාංශගත කර ඇත.

197class Generator(nn.Module):
  • log_resolution රූප විභේදනයේ වේ
  • d_latent හි මානයන් වේ
  • n_features වැඩිම යෝජනාව දී convolution ස්ථරය විශේෂාංග සංඛ්යාව (අවසාන වාරණ)
  • max_features ඕනෑම උත්පාදක වාරණයක උපරිම විශේෂාංග ගණන
214    def __init__(self, log_resolution: int, d_latent: int, n_features: int = 32, max_features: int = 512):
221        super().__init__()

එක්එක් කොටස සඳහා විශේෂාංග ගණන ගණනය කරන්න

වගේදෙයක් [512, 512, 256, 128, 64, 32]

226        features = [min(max_features, n_features * (2 ** i)) for i in range(log_resolution - 2, -1, -1)]

උත්පාදකකුට්ටි ගණන

228        self.n_blocks = len(features)

පුහුණුකළ හැකි නියතය

231        self.initial_constant = nn.Parameter(torch.randn((1, features[0], 4, 4)))

RGBලබා ගැනීම සඳහා විභේදනය සහ ස්ථරය සඳහා පළමු විලාසිතාවේ කොටස

234        self.style_block = StyleBlock(d_latent, features[0], features[0])
235        self.to_rgb = ToRGB(d_latent, features[0])

උත්පාදකකුට්ටි

238        blocks = [GeneratorBlock(d_latent, features[i - 1], features[i]) for i in range(1, self.n_blocks)]
239        self.blocks = nn.ModuleList(blocks)

නියැදි ස්ථරය දක්වා. විශේෂාංග අවකාශය එක් එක් වාරණ දී sampled දක්වා

ඇත
243        self.up_sample = UpSample()
  • w වේ . මිශ්ර-මෝස්තර සඳහා (විවිධ ස්ථර සඳහා වෙනස් භාවිතා කරන්න), අපි එක් එක් උත්පාදක කොටස සඳහා වෙනම ලබා දෙන්නෙමු. එහි හැඩය ඇත [n_blocks, batch_size, d_latent] .
  • input_noise යනු එක් එක් කොටස සඳහා ශබ්දය. එක් එක් වාරණ (ආරම්භක හැර) එක් එක් convolution ස්ථරය පසු ශබ්ද යෙදවුම් දෙකක් ඇති නිසා එය ශබ්ද සංවේදක යුගල ලැයිස්තුවකි (රූප සටහන බලන්න).
245    def forward(self, w: torch.Tensor, input_noise: List[Tuple[Optional[torch.Tensor], Optional[torch.Tensor]]]):

කණ්ඩායම්ප්රමාණය ලබා ගන්න

255        batch_size = w.shape[1]

කණ්ඩායම්ප්රමාණයට ගැලපෙන පරිදි උගත් නියතය පුළුල් කරන්න

258        x = self.initial_constant.expand(batch_size, -1, -1, -1)

පළමුවිලාසිතාවේ කොටස

261        x = self.style_block(x, w[0], input_noise[0][1])

පළමුrgb රූපය ලබා ගන්න

263        rgb = self.to_rgb(x, w[0])

ඉතිරිකොටස් තක්සේරු කරන්න

266        for i in range(1, self.n_blocks):

විශේෂාංගසිතියම සාම්පල කරන්න

268            x = self.up_sample(x)

උත්පාදක කොටස හරහා එය ධාවනය කරන්න

270            x, rgb_new = self.blocks[i - 1](x, w[i], input_noise[i])

ඉහළටRGB රූපය සාම්පල කර බ්ලොක් එකෙන් rgb වෙත එක් කරන්න

272            rgb = self.up_sample(rgb) + rgb_new

අවසානRGB රූපය ආපසු ලබා දෙන්න

275        return rgb

උත්පාදකබ්ලොක්

Generator block

රේඛීය ස්ථරයක් දක්වයි. විකාශන හා පරිමාණ මෙහෙයුමක් දක්වයි (ශබ්දය තනි නාලිකාවකි). toRGB ශෛලීය මොඩියුලේෂන් එකක් ද ඇති අතර එය සරල ලෙස තබා ගැනීම සඳහා රූප සටහනේ පෙන්වා නැත.

උත්පාදකකොටස ශෛලීය කුට්ටි දෙකකින් (ශෛලීය මොඩියුලේෂන් සහිත කැටි කිරීම්) සහ RGB ප්රතිදානයකින් සමන්විත වේ.

278class GeneratorBlock(nn.Module):
  • d_latent හි මානයන් වේ
  • in_features ආදාන විශේෂාංග සිතියමේ විශේෂාංග ගණන වේ
  • out_features ප්රතිදාන විශේෂාංග සිතියමේ ඇති විශේෂාංග ගණන
294    def __init__(self, d_latent: int, in_features: int, out_features: int):
300        super().__init__()

පළමු විලාසිතාවේ බ්ලොක් විශේෂාංග සිතියම් ප්රමාණය වෙනස් කරයි out_features

303        self.style_block1 = StyleBlock(d_latent, in_features, out_features)
305        self.style_block2 = StyleBlock(d_latent, out_features, out_features)

ටොර්ජීබී ස්ථරය

308        self.to_rgb = ToRGB(d_latent, out_features)
  • x හැඩයේ ආදාන විශේෂාංග සිතියමයි [batch_size, in_features, height, width]
  • w හැඩය සමඟ ඇත [batch_size, d_latent]
  • noise හැඩය ශබ්ද tensors දෙකක් tuple වේ [batch_size, 1, height, width]
310    def forward(self, x: torch.Tensor, w: torch.Tensor, noise: Tuple[Optional[torch.Tensor], Optional[torch.Tensor]]):

පළමුශබ්ද ටෙන්සර් සහිත පළමු විලාසිතාවේ කොටස. ප්රතිදානය හැඩයෙන් යුක්ත වේ [batch_size, out_features, height, width]

318        x = self.style_block1(x, w, noise[0])

දෙවනශබ්ද ටෙන්සර් සහිත දෙවන විලාසිතාවේ කොටස. ප්රතිදානය හැඩයෙන් යුක්ත වේ [batch_size, out_features, height, width]

321        x = self.style_block2(x, w, noise[1])

RGBරූපය ලබා ගන්න

324        rgb = self.to_rgb(x, w)

විශේෂාංගසිතියම සහ rgb රූපය ආපසු ලබා දෙන්න

327        return x, rgb

බ්ලොක්ස්ටයිල්

Style block

රේඛීය ස්ථරයක් දක්වයි. විකාශන හා පරිමාණ මෙහෙයුමක් දක්වයි (ශබ්දය තනි නාලිකාවකි).

ස්ටයිල්බ්ලොක් බර මොඩියුලේෂන් කැටි කිරීමේ තට්ටුවක් ඇත.

330class StyleBlock(nn.Module):
  • d_latent හි මානයන් වේ
  • in_features ආදාන විශේෂාංග සිතියමේ විශේෂාංග ගණන වේ
  • out_features ප්රතිදාන විශේෂාංග සිතියමේ ඇති විශේෂාංග ගණන
344    def __init__(self, d_latent: int, in_features: int, out_features: int):
350        super().__init__()

සමාන ඉගෙනීම-අනුපාත රේඛීය ස්ථරයක් සමඟ (රූප සටහනෙන් දැක්වේ) ශෛලීය දෛශිකය ලබා ගන්න

353        self.to_style = EqualizedLinear(d_latent, in_features, bias=1.0)

සිරුරේබර මොඩියුලේටඩ් කැටි ගැසුණු ස්ථරය

355        self.conv = Conv2dWeightModulate(in_features, out_features, kernel_size=3)

ශබ්දපරිමාණය

357        self.scale_noise = nn.Parameter(torch.zeros(1))

නැඹුරුව

359        self.bias = nn.Parameter(torch.zeros(out_features))

සක්රියකිරීමේ කාර්යය

362        self.activation = nn.LeakyReLU(0.2, True)
  • x හැඩයේ ආදාන විශේෂාංග සිතියමයි [batch_size, in_features, height, width]
  • w හැඩය සමඟ ඇත [batch_size, d_latent]
  • noise හැඩයේ ආතතිකාරයකි [batch_size, 1, height, width]
364    def forward(self, x: torch.Tensor, w: torch.Tensor, noise: Optional[torch.Tensor]):

දෛශිකශෛලිය ලබා ගන්න

371        s = self.to_style(w)

බරමොඩියුලේටඩ් කැටි ගැසිම

373        x = self.conv(x, s)

පරිමාණයකර ශබ්දය එක් කරන්න

375        if noise is not None:
376            x = x + self.scale_noise[None, :, None, None] * noise

නැඹුරුවඑකතු කර සක්රිය කිරීමේ කාර්යය ඇගයීමට ලක් කරන්න

378        return self.activation(x + self.bias[None, :, None, None])

RGBවෙත

To RGB

රේඛීය ස්ථරයක් දක්වයි.

සංවලිත භාවිතයෙන් විශේෂාංග සිතියමකින් RGB රූපයක් ජනනය කරයි.

381class ToRGB(nn.Module):
  • d_latent හි මානයන් වේ
  • features විශේෂාංග සිතියමේ විශේෂාංග ගණන
394    def __init__(self, d_latent: int, features: int):
399        super().__init__()

සමාන ඉගෙනීම-අනුපාත රේඛීය ස්ථරයක් සමඟ (රූප සටහනෙන් දැක්වේ) ශෛලීය දෛශිකය ලබා ගන්න

402        self.to_style = EqualizedLinear(d_latent, features, bias=1.0)

ඩිමොඩියුලේෂන්නොමැතිව බර මොඩියුලේටඩ් කැටි ගැසුණු ස්ථරය

405        self.conv = Conv2dWeightModulate(features, 3, kernel_size=1, demodulate=False)

නැඹුරුව

407        self.bias = nn.Parameter(torch.zeros(3))

සක්රියකිරීමේ කාර්යය

409        self.activation = nn.LeakyReLU(0.2, True)
  • x හැඩයේ ආදාන විශේෂාංග සිතියමයි [batch_size, in_features, height, width]
  • w හැඩය සමඟ ඇත [batch_size, d_latent]
411    def forward(self, x: torch.Tensor, w: torch.Tensor):

දෛශිකශෛලිය ලබා ගන්න

417        style = self.to_style(w)

බරමොඩියුලේටඩ් කැටි ගැසිම

419        x = self.conv(x, style)

නැඹුරුවඑකතු කර සක්රිය කිරීමේ කාර්යය ඇගයීමට ලක් කරන්න

421        return self.activation(x + self.bias[None, :, None, None])

බරමොඩියුලේෂන් සහ ඩිමොඩියුලේෂන් සමඟ සංකෝචනය

මෙමස්තරය ශෛලීය දෛශිකය මගින් සංවහන බර පරිමාණයට ලක් කරන අතර එය සාමාන්යකරණය කිරීමෙන් ඩිමොඩියුලේට් කරයි.

424class Conv2dWeightModulate(nn.Module):
  • in_features ආදාන විශේෂාංග සිතියමේ විශේෂාංග ගණන වේ
  • out_features ප්රතිදාන විශේෂාංග සිතියමේ ඇති විශේෂාංග ගණන
  • kernel_size යනු සංවහන කර්නලයේ ප්රමාණයයි
  • demodulate ධජය යනු එහි සම්මත අපගමනය අනුව බර සාමාන්යකරණය කළ යුතුද යන්නයි
  • eps සාමාන්යකරණය සඳහා වේ
  • 431    def __init__(self, in_features: int, out_features: int, kernel_size: int,
    432                 demodulate: float = True, eps: float = 1e-8):
    440        super().__init__()

    නිමැවුම්විශේෂාංග ගණන

    442        self.out_features = out_features

    බරසාමාන්යකරණය කළ යුතුද යන්න

    444        self.demodulate = demodulate

    පෑඩින්ප්රමාණය

    446        self.padding = (kernel_size - 1) // 2
    449        self.weight = EqualizedWeight([out_features, in_features, kernel_size, kernel_size])

    451        self.eps = eps
    • x හැඩයේ ආදාන විශේෂාංග සිතියමයි [batch_size, in_features, height, width]
    • s හැඩයේ ශෛලිය මත පදනම් වූ පරිමාණ ආතන්ය [batch_size, in_features]
    453    def forward(self, x: torch.Tensor, s: torch.Tensor):

    කණ්ඩායම්ප්රමාණය, උස සහ පළල ලබා ගන්න

    460        b, _, h, w = x.shape

    පරිමාණයන්නැවත සකස් කරන්න

    463        s = s[:, None, :, None, None]
    465        weights = self.weight()[None, :, :, :, :]

    ආදාන නාලිකාව යනු ප්රතිදාන නාලිකාව වන අතර කර්නල් දර්ශකය වේ.

    ප්රතිresult ලය හැඩය ඇත [batch_size, out_features, in_features, kernel_size, kernel_size]

    470        weights = weights * s

    විරූපණයකරන්න

    473        if self.demodulate:

    475            sigma_inv = torch.rsqrt((weights ** 2).sum(dim=(2, 3, 4), keepdim=True) + self.eps)

    477            weights = weights * sigma_inv

    නැවතහැඩගස්වා x

    480        x = x.reshape(1, -1, h, w)

    බරනැවත සකස් කරන්න

    483        _, _, *ws = weights.shape
    484        weights = weights.reshape(b * self.out_features, *ws)

    නියැදිනැණවත් කර්නලය සමඟ සංකෝචනය කාර්යක්ෂමව ගණනය කිරීම සඳහා කාණ්ඩගත කැටි ගැන්විම භාවිතා කරන්න. එනම් කණ්ඩායමේ එක් එක් නියැදිය සඳහා අපට වෙනස් කර්නලයක් (බර) ඇත

    488        x = F.conv2d(x, weights, padding=self.padding, groups=b)

    නැවත x [batch_size, out_features, height, width] හැඩගස්වා ආපසු යන්න

    491        return x.reshape(-1, self.out_features, h, w)

    StyleGan2 වෙනස්කම් කරන්නා

    Discriminator

    වෙනස්කම්කරන්නා පළමුව රූපය එකම විභේදනයේ විශේෂාංග සිතියමකට පරිවර්තනය කර පසුව අවශේෂ සම්බන්ධතා සහිත කුට්ටි මාලාවක් හරහා එය ධාවනය කරයි. විශේෂාංග ගණන දෙගුණ කරන අතර විභේදනය එක් එක් බ්ලොක් එකේ පහළ-නියැදි කර ඇත.

    494class Discriminator(nn.Module):
    • log_resolution රූප විභේදනයේ වේ
    • n_features වැඩිම යෝජනාව දී convolution ස්ථරය විශේෂාංග සංඛ්යාව (පළමු වාරණ)
    • max_features ඕනෑම උත්පාදක වාරණයක උපරිම විශේෂාංග ගණන
    508    def __init__(self, log_resolution: int, n_features: int = 64, max_features: int = 512):
    514        super().__init__()

    RGBරූපය විශේෂාංග n_features ගණනාවක් සහිත විශේෂාංග සිතියමක් බවට පරිවර්තනය කිරීමේ ස්ථරය.

    517        self.from_rgb = nn.Sequential(
    518            EqualizedConv2d(3, n_features, 1),
    519            nn.LeakyReLU(0.2, True),
    520        )

    එක්එක් කොටස සඳහා විශේෂාංග ගණන ගණනය කරන්න.

    වගේදෙයක් [64, 128, 256, 512, 512, 512] .

    525        features = [min(max_features, n_features * (2 ** i)) for i in range(log_resolution - 1)]
    527        n_blocks = len(features) - 1

    වෙනස්කම්කරන්නා කුට්ටි

    529        blocks = [DiscriminatorBlock(features[i], features[i + 1]) for i in range(n_blocks)]
    530        self.blocks = nn.Sequential(*blocks)
    533        self.std_dev = MiniBatchStdDev()

    සම්මතඅපගමනය සිතියම එකතු කිරීමෙන් පසු විශේෂාංග ගණන

    535        final_features = features[-1] + 1

    අවසාන කැටි ගැසුණු ස්ථරය

    537        self.conv = EqualizedConv2d(final_features, final_features, 3)

    වර්ගීකරණයලබා ගැනීම සඳහා අවසාන රේඛීය ස්ථරය

    539        self.final = EqualizedLinear(2 * 2 * final_features, 1)
    • x යනු හැඩයේ ආදාන රූපයයි [batch_size, 3, height, width]
    541    def forward(self, x: torch.Tensor):

    රූපයසාමාන්යකරණය කිරීමට උත්සාහ කරන්න (මෙය මුළුමනින්ම විකල්පයකි, නමුත් මුල් පුහුණුව ටිකක් වේගවත් කරන්න)

    547        x = x - 0.5

    RGBවෙතින් පරිවර්තනය කරන්න

    549        x = self.from_rgb(x)

    වෙනස්කම් කරන්නා කුට්ටි හරහා ධාවනය කරන්න

    551        x = self.blocks(x)

    කුඩා කණ්ඩායම් සම්මත අපගමනය ගණනය කිරීම සහ තක්සේරු කිරීම

    554        x = self.std_dev(x)

    කැටි ගැසිම

    556        x = self.conv(x)

    සමතලාකරන්න

    558        x = x.reshape(x.shape[0], -1)

    වර්ගීකරණලකුණු ආපසු ලබා දෙන්න

    560        return self.final(x)

    වෙනස්කම්කරන්නා බ්ලොක්

    Discriminator block

    Disturistatorබ්ලොක් අවශේෂ සම්බන්ධතාවයක් සහිත ව්යාංජන දෙකකින් සමන්විත වේ.

    563class DiscriminatorBlock(nn.Module):
    • in_features ආදාන විශේෂාංග සිතියමේ විශේෂාංග ගණන වේ
    • out_features ප්රතිදාන විශේෂාංග සිතියමේ ඇති විශේෂාංග ගණන
    574    def __init__(self, in_features, out_features):
    579        super().__init__()

    අවශේෂසම්බන්ධතාවය සඳහා පහළ-නියැදීම් සහ කැටි ගැසීම ස්ථරය

    581        self.residual = nn.Sequential(DownSample(),
    582                                      EqualizedConv2d(in_features, out_features, kernel_size=1))

    ව්යාකූලතා දෙකක්

    585        self.block = nn.Sequential(
    586            EqualizedConv2d(in_features, in_features, kernel_size=3, padding=1),
    587            nn.LeakyReLU(0.2, True),
    588            EqualizedConv2d(in_features, out_features, kernel_size=3, padding=1),
    589            nn.LeakyReLU(0.2, True),
    590        )

    පහළ-නියැදිස්ථරය

    593        self.down_sample = DownSample()

    අවශේෂඑකතු කිරීමෙන් පසු පරිමාණ සාධකය

    596        self.scale = 1 / math.sqrt(2)
    598    def forward(self, x):

    අවශේෂසම්බන්ධතාවය ලබා ගන්න

    600        residual = self.residual(x)

    සම්මුතීන්

    603        x = self.block(x)

    පහළ-නියැදිය

    605        x = self.down_sample(x)

    අවශේෂසහ පරිමාණය එකතු කරන්න

    608        return (x + residual) * self.scale

    කුඩාකණ්ඩායම සම්මත අපගමනය

    කුඩාකණ්ඩායම් සම්මත අපගමනය විශේෂාංග සිතියමේ ඇති එක් එක් ලක්ෂණය සඳහා කුඩා කණ්ඩායමක් (හෝ කුඩා කණ්ඩායම තුළ ඇති උප කණ්ඩායම්) හරහා සම්මත අපගමනය ගණනය කරයි. එවිට එය සියලු සම්මත අපගමනයන්හි මධ්යන්යය ගෙන එය එක් අමතර අංගයක් ලෙස විශේෂාංග සිතියමට එකතු කරයි.

    611class MiniBatchStdDev(nn.Module):
    • group_size සම්මත අපගමනය ගණනය කිරීම සඳහා සාම්පල ගණන වේ.
    623    def __init__(self, group_size: int = 4):
    627        super().__init__()
    628        self.group_size = group_size
    • x විශේෂාංග සිතියමයි
    630    def forward(self, x: torch.Tensor):

    කණ්ඩායම්ප්රමාණය කණ්ඩායම් ප්රමාණය අනුව බෙදිය හැකි දැයි පරීක්ෂා කරන්න

    635        assert x.shape[0] % self.group_size == 0

    සාම්පලකණ්ඩායම් වලට බෙදන්න group_size , එක් එක් ලක්ෂණය සඳහා සම්මත අපගමනය ගණනය කිරීමට අපට අවශ්ය බැවින් අපි විශේෂාංග සිතියම තනි මානයකට සමතලා කරමු.

    638        grouped = x.view(self.group_size, -1)

    group_size සාම්පල අතර එක් එක් ලක්ෂණය සඳහා සම්මත අපගමනය ගණනය

    645        std = torch.sqrt(grouped.var(dim=0) + 1e-8)

    මධ්යන්යසම්මත අපගමනය ලබා ගන්න

    647        std = std.mean().view(1, 1, 1, 1)

    විශේෂාංගසිතියමට එක් කිරීම සඳහා සම්මත අපගමනය පුළුල් කරන්න

    649        b, _, h, w = x.shape
    650        std = std.expand(b, -1, h, w)

    විශේෂාංගසිතියමට සම්මත අපගමනය (සංයුක්ත කරන්න)

    652        return torch.cat([x, std], dim=1)
    655class DownSample(nn.Module):
    667    def __init__(self):
    668        super().__init__()

    ස්තරයසුමටනය

    670        self.smooth = Smooth()
    672    def forward(self, x: torch.Tensor):

    සුමටනයහෝ බොඳ කිරීම

    674        x = self.smooth(x)

    පහළටපරිමාණය කර ඇත

    676        return F.interpolate(x, (x.shape[2] // 2, x.shape[3] // 2), mode='bilinear', align_corners=False)

    ඉහළනියැදිය

    දක්වා-නියැදිමෙහෙයුම මඟින් රූපය ඉහළට ගෙන යන අතර එක් එක් විශේෂාංග නාලිකාව සුමටනය කරයි . මෙය පදනම් වී ඇත්තේ කඩදාසි මත ය Convolutional Networks Shift-Invariant නැවතත්.

    679class UpSample(nn.Module):
    690    def __init__(self):
    691        super().__init__()

    දක්වා-නියැදීම්ස්ථරය

    693        self.up_sample = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=False)

    ස්තරයසුමටනය

    695        self.smooth = Smooth()
    697    def forward(self, x: torch.Tensor):

    ඉහළටනියැදිය සහ සුමටනය

    699        return self.smooth(self.up_sample(x))

    ස්ථරයසුමටනය

    මෙමස්තරය එක් එක් නාලිකාව බොඳ කරයි

    702class Smooth(nn.Module):
    711    def __init__(self):
    712        super().__init__()

    කර්නලයබොඳ කිරීම

    714        kernel = [[1, 2, 1],
    715                  [2, 4, 2],
    716                  [1, 2, 1]]

    කර්නලයPyTorch ටෙන්සරයක් බවට පරිවර්තනය කරන්න

    718        kernel = torch.tensor([[kernel]], dtype=torch.float)

    කර්නලයසාමාන්යකරණය කරන්න

    720        kernel /= kernel.sum()

    කර්නලයස්ථාවර පරාමිතියක් ලෙස සුරකින්න (ශ්රේණියේ යාවත්කාලීන කිරීම් නොමැත)

    722        self.kernel = nn.Parameter(kernel, requires_grad=False)

    පෑඩින්ස්ථරය

    724        self.pad = nn.ReplicationPad2d(1)
    726    def forward(self, x: torch.Tensor):

    ආදානවිශේෂාංග සිතියමේ හැඩය ලබා ගන්න

    728        b, c, h, w = x.shape

    සුමටනයසඳහා නැවත සකස් කරන්න

    730        x = x.view(-1, 1, h, w)

    පෑඩින්එකතු කරන්න

    733        x = self.pad(x)

    කර්නලයසමඟ සුමටනය (බොඳ කිරීම)

    736        x = F.conv2d(x, self.kernel)

    නැවතහැඩගස්වා නැවත පැමිණීම

    739        return x.view(b, c, h, w)

    ඉගෙනීම-අනුපාතසමාන රේඛීය ස්ථරය

    මෙයරේඛීය ස්තරයක් සඳහා ඉගෙනීමේ අනුපාත සමාන බර භාවිතා කරයි.

    742class EqualizedLinear(nn.Module):
    • in_features ආදාන විශේෂාංග සිතියමේ විශේෂාංග ගණන වේ
    • out_features ප්රතිදාන විශේෂාංග සිතියමේ ඇති විශේෂාංග ගණන
    • bias යනු නැඹුරුව ආරම්භ කිරීම නියතය
    751    def __init__(self, in_features: int, out_features: int, bias: float = 0.):
    758        super().__init__()
    760        self.weight = EqualizedWeight([out_features, in_features])

    නැඹුරුව

    762        self.bias = nn.Parameter(torch.ones(out_features) * bias)
    764    def forward(self, x: torch.Tensor):

    රේඛීයපරිවර්තනය

    766        return F.linear(x, self.weight(), bias=self.bias)

    ඉගෙනුම්-අනුපාතසමාන 2D සම්මුතිය ස්ථරය

    මෙයකැටි ගැසුණු ස්ථරයක් සඳහා ඉගෙනීම-අනුපාත සමාන බර භාවිතා කරයි.

    769class EqualizedConv2d(nn.Module):
    • in_features ආදාන විශේෂාංග සිතියමේ විශේෂාංග ගණන වේ
    • out_features ප්රතිදාන විශේෂාංග සිතියමේ ඇති විශේෂාංග ගණන
    • kernel_size යනු සංවහන කර්නලයේ ප්රමාණයයි
  • padding එක් එක් ප්රමාණයේ මානයන්හි දෙපස එකතු කළ යුතු පෑඩින් වේ
  • 778    def __init__(self, in_features: int, out_features: int,
    779                 kernel_size: int, padding: int = 0):
    786        super().__init__()

    පෑඩින්ප්රමාණය

    788        self.padding = padding
    790        self.weight = EqualizedWeight([out_features, in_features, kernel_size, kernel_size])

    නැඹුරුව

    792        self.bias = nn.Parameter(torch.ones(out_features))
    794    def forward(self, x: torch.Tensor):

    සංවලිත

    796        return F.conv2d(x, self.weight(), bias=self.bias, padding=self.padding)

    ඉගෙනීම-අනුපාතයසමාන බර පරාමිතිය

    මෙයපදනම් වී ඇත්තේ ප්රගතිශීලී GAN කඩදාසි වල හඳුන්වා දී ඇති සමාන ඉගෙනුම් අනුපාතය මත ය. ඔවුන් බර ආරම්භ කරනවා වෙනුවට බර ආරම්භ කර එය භාවිතා කරන විට ඒවා ගුණ කරන්න.

    ගබඩාකරන ලද පරාමිතීන්හි අනුක්රමික ගුණ කරන නමුත් ආදම් වැනි ප්රශස්තිකයන් වර්ග කළ ශ්රේණියක ධාවන මධ්යන්යයකින් ඒවා සාමාන්යකරණය කරන බැවින් මෙයට බලපෑමක් ඇති නොකරයි.

    ප්රශස්තිකරණයාවත්කාලීන කිරීම් ඉගෙනුම් අනුපාතයට සමානුපාතික වේ. නමුත් ඵලදායී පඩි සමානුපාතිකව යාවත්කාලීන වේ . සමාන ඉගෙනුම් අනුපාතය තොරව, ඵලදායී පඩි පමණක් සමානුපාතිකව යාවත්කාලීන ලැබෙනු ඇත .

    එබැවින්අපි මෙම බර පරාමිතීන් සඳහා ඉගෙනුම් අනුපාතය effectively ලදායී ලෙස පරිමාණය කරමු.

    799class EqualizedWeight(nn.Module):
    • shape බර පරාමිතියේ හැඩයයි
    820    def __init__(self, shape: List[int]):
    824        super().__init__()

    ඔහුආරම්භ කිරීම නියතය

    827        self.c = 1 / math.sqrt(np.prod(shape[1:]))

    සමඟබර ආරම්භ කරන්න

    829        self.weight = nn.Parameter(torch.randn(shape))

    බරගුණ කිරීමේ සංගුණකය

    832    def forward(self):

    බරවැඩි කර ආපසු යන්න

    834        return self.weight * self.c

    ග්රේඩියන්ට්දඬුවම

    කඩදාසිවලින් විධිමත් කිරීමේ ද ality ුවම මෙයයි GANs සඳහා පුහුණු ක්රම ඇත්ත වශයෙන්ම අභිසාරී වන්නේ කුමක්ද? .

    ඒතමයි අපි රූප සම්බන්ධයෙන් වෙනස්කම් කරන්නාගේ L2 සම්මතය අඩු කිරීමට උත්සාහ කරන්නේ සැබෑ රූප සඳහා ().

    837class GradientPenalty(nn.Module):
    • x වේ
  • d වේ
  • 853    def forward(self, x: torch.Tensor, d: torch.Tensor):

    කණ්ඩායම්ප්රමාණය ලබා ගන්න

    860        batch_size = x.shape[0]

    සම්බන්ධයෙන්අනුක්රමික ගණනය කරන්න . grad_outputs අපට අනුක්රමික අවශ්ය බැවින් සකසා ඇති අතර , මෙම අලාභය මත බර සම්බන්ධයෙන් අනුක්රමික ගණනය කළ යුතු බැවින් අපි ප්රස්ථාරයක් නිර්මාණය කර රඳවා තබා ගත යුතුය.

    866        gradients, *_ = torch.autograd.grad(outputs=d,
    867                                            inputs=x,
    868                                            grad_outputs=d.new_ones(d.shape),
    869                                            create_graph=True)

    සම්මතයගණනය කිරීම සඳහා අනුක්රමික නැවත සකස් කරන්න

    872        gradients = gradients.reshape(batch_size, -1)

    සම්මතයගණනය කරන්න

    874        norm = gradients.norm(2, dim=-1)

    අලාභයආපසු ලබා දෙන්න

    876        return torch.mean(norm ** 2)

    මාර්ගයදිග දණ්ඩන

    මෙමනියාමනය මඟින් රූපයේ ස්ථාවර ප්රමාණයේ වෙනසක් ඇති කිරීම සඳහා ස්ථාවර ප්රමාණයේ පියවරක් දිරිමත් කරයි.

    ජැකෝබියන් කොහෙද , සිතියම්කරණ ජාලයෙන් සාම්පල ලබා ඇත, සහ ඒවා ශබ්දය සහිත රූප .

    පුහුණුව ඉදිරියට යත්ම ඝාතීය චලනය වන සාමාන්යය වේ.

    ජැකොබියන් භාවිතයෙන් පැහැදිලිව ගණනය නොකර ගණනය කරනු ලැබේ

    879class PathLengthPenalty(nn.Module):
    • beta ඝාතීය චලනය වන සාමාන්යය ගණනය කිරීම සඳහා භාවිතා කරන නියතය
    903    def __init__(self, beta: float):
    907        super().__init__()

    910        self.beta = beta

    ගණනයකරන ලද පියවර ගණන

    912        self.steps = nn.Parameter(torch.tensor(0.), requires_grad=False)

    පුහුණුවේ -th පියවරේදී එහි වටිනාකම කොතැනද? ඝාතීය එකතුව

    916        self.exp_sum_a = nn.Parameter(torch.tensor(0.), requires_grad=False)
    • w හැඩයේ කණ්ඩායමයි [batch_size, d_latent]
    • x හැඩයේ ජනනය කරන ලද රූප වේ [batch_size, 3, height, width]
    918    def forward(self, w: torch.Tensor, x: torch.Tensor):

    උපාංගයලබා ගන්න

    925        device = x.device

    පික්සල්ගණන ලබා ගන්න

    927        image_size = x.shape[2] * x.shape[3]

    ගණනයකරන්න

    929        y = torch.randn(x.shape, device=device)

    රූපප්රමාණයේ වර්ග මූලය ගණනය කර සාමාන්යකරණය කරන්න. මෙය පරිමාණය යනු කඩදාසි වල සඳහන් නොවන නමුත් ඒවා ක්රියාත්මකකිරීමේදී දක්නට ලැබුණි.

    933        output = (x * y).sum() / math.sqrt(image_size)

    ලබාගැනීම සඳහා අනුක්රමික ගණනය කරන්න

    936        gradients, *_ = torch.autograd.grad(outputs=output,
    937                                            inputs=w,
    938                                            grad_outputs=torch.ones(output.shape, device=device),
    939                                            create_graph=True)

    L2හි සාමාන්යය ගණනය කරන්න

    942        norm = (gradients ** 2).sum(dim=2).mean(dim=1).sqrt()

    පළමුපියවරෙන් පසු විධිමත් කරන්න

    945        if self.steps > 0:

    ගණනයකරන්න

    948            a = self.exp_sum_a / (1 - self.beta ** self.steps)

    දpenalty ුවම ගණනය කරන්න

    952            loss = torch.mean((norm - a) ** 2)
    953        else:

    අපටගණනය කළ නොහැකි නම් ව්යාජ අලාභයක් ආපසු ලබා දෙන්න

    955            loss = norm.new_tensor(0)

    මධ්යන්යයගණනය කරන්න

    958        mean = norm.mean().detach()

    ඝාතීයමුදලක් යාවත්කාලීන කරන්න

    960        self.exp_sum_a.mul_(self.beta).add_(mean, alpha=1 - self.beta)

    වර්ධකය

    962        self.steps.add_(1.)

    දpenalty ුවම ආපසු දෙන්න

    965        return loss