Shortcuts

mmedit.models.editors.stylegan1.stylegan1_discriminator 源代码

# Copyright (c) OpenMMLab. All rights reserved.
import numpy as np
import torch.nn as nn
import torch.nn.functional as F

from mmedit.registry import MODELS
from ..pggan import (EqualizedLRConvDownModule, EqualizedLRConvModule,
                     MiniBatchStddevLayer)
from .stylegan1_modules import Blur, EqualLinearActModule


@MODELS.register_module('StyleGANv1Discriminator')
@MODELS.register_module()
[文档]class StyleGAN1Discriminator(nn.Module): """StyleGAN1 Discriminator. The architecture of this discriminator is proposed in StyleGAN1. More details can be found in: A Style-Based Generator Architecture for Generative Adversarial Networks CVPR2019. Args: in_size (int): The input size of images. blur_kernel (list, optional): The blurry kernel. Defaults to [1, 2, 1]. mbstd_cfg (dict, optional): Configs for minibatch-stddev layer. Defaults to dict(group_size=4). """ def __init__(self, in_size, blur_kernel=[1, 2, 1], mbstd_cfg=dict(group_size=4)): super().__init__() self.with_mbstd = mbstd_cfg is not None channels = { 4: 512, 8: 512, 16: 512, 32: 512, 64: 256, 128: 128, 256: 64, 512: 32, 1024: 16, } log_size = int(np.log2(in_size)) self.log_size = log_size in_channels = channels[in_size] self.convs = nn.ModuleList() self.from_rgb = nn.ModuleList() for i in range(log_size, 2, -1): out_channel = channels[2**(i - 1)] self.from_rgb.append( EqualizedLRConvModule( 3, in_channels, kernel_size=3, padding=1, act_cfg=dict(type='LeakyReLU', negative_slope=0.2))) self.convs.append( nn.Sequential( EqualizedLRConvModule( in_channels, out_channel, kernel_size=3, padding=1, bias=True, norm_cfg=None, act_cfg=dict(type='LeakyReLU', negative_slope=0.2)), Blur(blur_kernel, pad=(1, 1)), EqualizedLRConvDownModule( out_channel, out_channel, kernel_size=3, stride=2, padding=1, act_cfg=None), nn.LeakyReLU(negative_slope=0.2, inplace=True))) in_channels = out_channel self.from_rgb.append( EqualizedLRConvModule( 3, in_channels, kernel_size=3, padding=0, act_cfg=dict(type='LeakyReLU', negative_slope=0.2))) self.convs.append( nn.Sequential( EqualizedLRConvModule( in_channels + 1, 512, kernel_size=3, padding=1, bias=True, norm_cfg=None, act_cfg=dict(type='LeakyReLU', negative_slope=0.2)), EqualizedLRConvModule( 512, 512, kernel_size=4, padding=0, bias=True, norm_cfg=None, act_cfg=None), )) if self.with_mbstd: self.mbstd_layer = MiniBatchStddevLayer(**mbstd_cfg) self.final_linear = nn.Sequential(EqualLinearActModule(channels[4], 1)) self.n_layer = len(self.convs)
[文档] def forward(self, input, transition_weight=1., curr_scale=-1): """Forward function. Args: input (torch.Tensor): Input image tensor. transition_weight (float, optional): The weight used in resolution transition. Defaults to 1.. curr_scale (int, optional): The resolution scale of image tensor. -1 means the max resolution scale of the StyleGAN1. Defaults to -1. Returns: torch.Tensor: Predict score for the input image. """ curr_log_size = self.log_size if curr_scale < 0 else int( np.log2(curr_scale)) step = curr_log_size - 2 for i in range(step, -1, -1): index = self.n_layer - i - 1 if i == step: out = self.from_rgb[index](input) # minibatch standard deviation if i == 0: out = self.mbstd_layer(out) out = self.convs[index](out) if i > 0: if i == step and 0 <= transition_weight < 1: skip_rgb = F.avg_pool2d(input, 2) skip_rgb = self.from_rgb[index + 1](skip_rgb) out = (1 - transition_weight ) * skip_rgb + transition_weight * out out = out.view(out.shape[0], -1) out = self.final_linear(out) return out