StyleGAN2 解释

2023-11-18

本文是[1]的译文, 按照作者Connor Shorten
的说法, 此博客讨论的是StyleGAN2的诸如weight demodulation, path length regularization和去掉progressive growing等信息。虽然我去年底自己复现过StyleGAN2的pytorch版, 但对这些内容也有些忘记了,借此机会复习下。
对于StyleGAN不了解的小伙伴,建议先看下别人写的关于StyleGAN的基本介绍,然后再来看本文,相信会收获更多~

0. 前言

来自Nvidia 赫尔辛基实验室的Karras等人提出的StyleGAN1的架构在Flicker-Faces-HQ (FFHQ)等数据集上表现非常惊人,相比之前的DCGAN和Conditional GAN等结构。

以FFHQ数据集为例,StyleGAN不但可以生成逼真的人脸(几乎无懈可击),而且能够对人脸进行解耦, 以便对人脸进行编辑(19年的论文,截至2020年10月中旬,引用已破千(截至2020年10月20日,是1232.),在twitter上也经常有用StyleGAN的latent space做文章的工作,比较典型的厉害人物有CUHK的沈宇军和周博磊)。

在这里插入图片描述

StyleGAN生成的人脸图像

在StyleGAN中, Frechet Inception Distance (FID) 是最常用的衡量图片真实性的指标(由法国科学家提出,也称遛狗绳距离)。
在这里插入图片描述

第一代StyleGAN[2]的实验表,可见,StyleGAN1在FFHQ最好的FID为4.40,FID越低越好。

在这里插入图片描述

第二代StyleGAN[3]的实验表,可见,StyleGAN2在FFHQ上的表现比第一代更好,其中,FID值由4.40提升到2.84. 算的上是巨大的提升了。

本文主要讨论StyleGAN2相比StyleGAN1在架构上的改变,正是这些改变使得FID指标有了显著提升~,定性观察上面,StyleGAN2的artifacts出现频率也显著比StyleGAN1低。

并基于很多人对latent space进行魔改的需求,对latent space进行平滑操作。

原作者搞了个17分钟的解释StyleGAN2的视频在下面,如果感兴趣的小伙伴,可以饭墙去看看[4]

在这里插入图片描述

1. 重大改进

1.1 Weight Demodulation

karras和ming-yu liu等大佬非常擅长用改造的normalization层进行image synthesis任务(如GauGAN和StyleGAN)。如GauGAN中的SPADE和StyleGAN的AdaIN

对StyleGAN,karras等人使用AdaIN (adaptive instance normalization)来控制source vector w w w对生成人脸的影响程度。

对StyleGAN2来讲,作者们调整了AdaIN的使用,从而有效的避免了水印artifacts(water droplet artifacts)

AdaIN是被用于快速Neural Style Transfer的normalization层。在Neural Style Transfer任务中,研究者们发现:AdaIN可以显著的解耦(remarkable disentanglement) low-level的"style"特征high-level的"content"特征

在这里插入图片描述

图像来自<Arbitrary Style Transfer in real-time with Adaptive Instance Normalization> authored by Xun Huang and Serge Belongie.

不同于一般的风格迁移(Style Transfer)任务,AdaIN的出现使得风格迁移任务从受限于一种风格或者需要lengthy optimization process的情况中摆脱了出来。

AdaIN表明,仅通过归一化统计就可以将风格(style)和内容(content)结合起来。

Karras等人在StyleGAN2中解释了AdaIN这种归一化方法会"discard information in feature maps encoded in the relative magnitudes of activations"。

生成器(Generator)通过将信息sneaking在这些层中来克服信息丢失的问题,但是这却带来了水印问题(water-droplet artifacts)

对于为什么鉴别器(Discriminator)不能识别水印,作者与读者有同样的困惑。

在StyleGAN2中,AdaIN被重构为Weight Demodulation, 如下所示:

  • AdaIN 层的含义: 同BN层类似,其目的是对网络中间层的输出结果进行scale和shift,以增加网络的学习效果,避免梯度消失。相对于BN是学习当前batch数据的mean和variance,Instance Norm则是采用了单张图片。AdaIN则是使用learnable的scale和shift参数去对齐特征图中的不同位置。
    在这里插入图片描述

a,b为StyleGAN的细节图,c和d为StyleGAN2的细节图。可以看出[5]normalization中不再需要mean,只计算std即可。并将noise模块移除style box中,如下所示[5]

在这里插入图片描述

Weight demodulation的处理流程如下

  • ① 如上图里面的©所示,Conv 3x3后面的Mod std被用于对卷积层的权重进行scaling(缩放)
    w i j k ′ = s i × w i j k w_{ijk}^{'} = s_{i} \times w_{ijk} wijk=si×wijk, 这里的 i i i表示第 i i i个特征图。

  • ② 接着对卷积层的权重进行demod
    σ j = ( ∑ i , k ( w i j k ′ ) 2 ) \sigma_j = \sqrt (\sum_{i,k} (w_{ijk}^{'})^2) σj=( i,k(wijk)2)
    那么,得到新的卷积层权重为
    在这里插入图片描述
    加一个小的 ϵ \epsilon ϵ是为了避免分母为0,保证数值稳定性。尽管这种方式与Instance Norm并非在数学上完全等价,但是weight demodulation同其它normalization 方法一样,使得输出特征图有着standard的unit和deviation。

    此外,将scaling参数挪为卷积层的权重使得计算路径可以更好的并行化。这种方式使得训练加速了约40%(从每秒处理37张图片到每秒处理61张图片—不知道作者用的是什么机器)。

1.2 Progressive growth

StyleGAN图像对鼻子和眼睛等面部特征有很强的位置偏好。作者Karras等人将此归因于progressive growing training (同Karras作品PGGAN[6],18年的论文,引用已经有2200左右了,Karras太强了。。。)

Progressive growing指的是:先训一个小分辨率的图像,训好了之后再逐步过渡到更高分辨率的图像。然后稳定训练当前分辨率,再逐步过渡到下一个更高的分辨率。

尽管对研究者来说,复现progressive growing非常令人头大(因为Karras他们全都是用tensorflow 1.x写的这些网络)。这需要复杂的循环和策略设计。但是总的来说,progressive growing还是属于一种比较直观的对高分辨率图像合成coarse-to-fine的方式。这是因为一般的GAN在训练超高分辨率( 102 4 2 1024^2 10242)的图像生成上面相当不稳定,按照作者的话说:

The discriminator will easily distinguish real and fake images, resulting in the generator unable to learn anything during training.

不同于StyleGAN第一代使用progressive growing的策略,StyleGAN2开始寻求其它的设计以便于让网络更深,并有着更好的训练稳定性。
对Resnet结构而言,网络加深是通过skip connection实现的。所以StyleGAN2采用了类似ResNet的残差连接结构(residual block)。对于这些设计,我们使用双线性滤波对前一层进行上/下采样,并尝试学习下一层的残差值(residual value)

如下图所示,Karras等人使用来自TomTom公司和Adobe研究院的作者提出的“Multi-Scale Gradients for Generative Adversarial Networks” MSG-GAN[7]来revisit之前的progressive growing的方式,从而更好的利用不同尺度的信息。

正是受MSG-GAN的启发,StyleGAN2设计了一个新的架构来利用图像生成的多个尺度信息(不需要像progressive growing那样麻烦了),他们通过一个resnet风格的跳跃连接在低分辨率的特征映射到最终生成的图像(下图的绿色block)

在这里插入图片描述

在这里插入图片描述

StyleGAN2的网络结构(受MSG-GAN启发)。

在这里插入图片描述

Here is the performance improvement using different approaches. FID越低越好,可以看出对G output加skip和对D 增加residual的组合效果最好。

作者表明MSG-GAN的方式同progressive growing类似,训练的早期更多地依赖低频/分辨率来对最终的输出产生影响。下图显示了特征图对最后输出的贡献情况。对这一点的研究促使Karras等人扩大网络规模,使1024x1024的分辨率对最终输出贡献更大。

在这里插入图片描述

1.3 Lazy Regularization

StyleGAN1对FFHQ数据集使用了R1正则化。实验结果表明,在评估计算代价的时候,regularization是可以忽略的。实际上,即使每隔16个mini-batch使用regularization的方式,模型效果依旧很不错,因此,在StyleGAN2中,我们可以使用lazy regularization的策略,即对数据分布开始跑偏的时候才使用R1 regularization,其它时候不使用。

1.4 Path Length Regularization

Path Length Regularization的意义是使得latent space的插值变得更加smooth和线性。简单来说,当在latent space中对latent vector进行插值操作时,我们希望对latent vector的等比例的变化直接反映到图像中去。即:“在latent space和image space应该有同样的变化幅度(线性的latent space)”(比如说,当你对某一组latent vector进行了5个degree的偏移,那么反映在最后的生成图像中,应该是同样的效果, 如下图所示)。
在这里插入图片描述
Karras等人通过对生成器(Generator) 增加了一个loss项来达到这个目标。
在这里插入图片描述
代码如下,简单来说就是计算生成器生成的图像对其latent vector的梯度(Jacobian矩阵), ∣ ∣ J w T y ∣ ∣ 2 ||J_w^Ty||_2 JwTy2就是代码中的pl_lengths, a a apl_mean_var的移动平均: pl_mean_var= pl_mean_var + 0.01 * ( m e a n mean mean(pl_lengths) - pl_mean_var)。

这种方法"dramatically facilitates projecting images back into the latent space"(让图像得到更加线性的对应latent vector)。

#----------------------------------------------------------------------------
# Non-saturating logistic loss with path length regularizer from the paper
# "Analyzing and Improving the Image Quality of StyleGAN", Karras et al. 2019

def G_logistic_ns_pathreg(G, D, opt, training_set, minibatch_size, pl_minibatch_shrink=2, pl_decay=0.01, pl_weight=2.0):
    _ = opt
    latents = tf.random_normal([minibatch_size] + G.input_shapes[0][1:])
    labels = training_set.get_random_labels_tf(minibatch_size)
    fake_images_out, fake_dlatents_out = G.get_output_for(latents, labels, is_training=True, return_dlatents=True)
    fake_scores_out = D.get_output_for(fake_images_out, labels, is_training=True)
    loss = tf.nn.softplus(-fake_scores_out) # -log(sigmoid(fake_scores_out))

    # Path length regularization.
    with tf.name_scope('PathReg'):

        # Evaluate the regularization term using a smaller minibatch to conserve memory.
        if pl_minibatch_shrink > 1:
            pl_minibatch = minibatch_size // pl_minibatch_shrink
            pl_latents = tf.random_normal([pl_minibatch] + G.input_shapes[0][1:])
            pl_labels = training_set.get_random_labels_tf(pl_minibatch)
            fake_images_out, fake_dlatents_out = G.get_output_for(pl_latents, pl_labels, is_training=True, return_dlatents=True)

        # Compute |J*y|.
        pl_noise = tf.random_normal(tf.shape(fake_images_out)) / np.sqrt(np.prod(G.output_shape[2:]))
        pl_grads = tf.gradients(tf.reduce_sum(fake_images_out * pl_noise), [fake_dlatents_out])[0]
        pl_lengths = tf.sqrt(tf.reduce_mean(tf.reduce_sum(tf.square(pl_grads), axis=2), axis=1))
        pl_lengths = autosummary('Loss/pl_lengths', pl_lengths)

        # Track exponential moving average of |J*y|.
        with tf.control_dependencies(None):
            pl_mean_var = tf.Variable(name='pl_mean', trainable=False, initial_value=0.0, dtype=tf.float32)
        pl_mean = pl_mean_var + pl_decay * (tf.reduce_mean(pl_lengths) - pl_mean_var)
        pl_update = tf.assign(pl_mean_var, pl_mean)

        # Calculate (|J*y|-a)^2.
        with tf.control_dependencies([pl_update]):
            pl_penalty = tf.square(pl_lengths - pl_mean)
            pl_penalty = autosummary('Loss/pl_penalty', pl_penalty)

        # Apply weight.
        #
        # Note: The division in pl_noise decreases the weight by num_pixels, and the reduce_mean
        # in pl_lengths decreases it by num_affine_layers. The effective weight then becomes:
        #
        # gamma_pl = pl_weight / num_pixels / num_affine_layers
        # = 2 / (r^2) / (log2(r) * 2 - 2)
        # = 1 / (r^2 * (log2(r) - 1))
        # = ln(2) / (r^2 * (ln(r) - ln(2))
        #
        reg = pl_penalty * pl_weight

    return loss, reg

#----------------------------------------------------------------------------

2. 感谢阅读

感谢阅读StyleGAN2的重要特性分析,谢谢~

参考文献

[1] StyleGAN2–medium
[2] StyleGAN: A Style-Based Generator Architecture for Generative Adversarial Networks
[3] StyleGAN2: Analyzing and Improving the Image Quality of StyleGAN
[4] StyleGANv2 Explained!
[5] GAN — StyleGAN & StyleGAN2 – Jonathan Hui
[6] PGGAN
[7] MSG-GAN
[8] StyleGAN2-pytorch

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

StyleGAN2 解释 的相关文章

随机推荐

  • win 11又更新,新功能简直绝了!

    很早之前 咱就知道微软下半年将会有一次大动作 没错 就是发布Win11 22H2正式版 之前有说过9月份发 现在也确实做到了 微软现在已经面向190多个国家 地区推送了Windows 11 22H2正式版更新 更新之后版本号为22621 5
  • linux中通过sed命令通过正则表达式过滤出中文[^[\u4E00-\u9FA5A-Za-z0-9_]+$]

    linux中通过sed命令通过正则表达式过滤出中文 sed r s u4E00 u9FA5A Za z0 9 lt gt 0 9 a z A Z g zz txt gt a txt
  • flutter listview 滚动到底部_(五) Flutter入门学习 之 Widget滚动

    列表是移动端经常使用的一种视图展示方式 在Flutter中提供了ListView和GridView 为了可能展示出更好的效果 我这里提供了一段Json数据 所以我们可以先学习一下Json解析 一 JSON读取和解析 在开发中 我们经常会使用
  • sql注入原理及解决方案

    sql注入原理就是用户输入动态的构造了意外sql语句 造成了意外结果 是攻击者有机可乘 SQL注入 SQL注入 就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串 最终达到欺骗服务器执行恶意的SQL命令 比如先前的很多
  • 随机练习题:浅浅固定思路

    1 牛牛的10类人 2 牛牛的四叶玫瑰数 3 牛牛的替换 4 牛牛的素数判断 笔者开头感想 如今大部分高校已经开学 当然笔者也不列外 但是由于疫情的原因 笔者被迫在家上网课学习 一脸忧愁 而这恰恰给了笔者自学的机会 相信笔者会加油滴 按照时
  • Acwing-4366. 上课睡觉

    假设最终答案为每堆石子均为cnt个 cnt一定可以整除sum 石子的总数 我们可以依次枚举答案 sum小于等于10 6 所以cnt的数量等于sum约数的个数 10 6范围内 约数最多的数为720720 它的约数个数有240个 int范围内
  • 单边带(SSB)调制技术

    文章目录 单边带 SSB 调制技术 1 双边带简述 2 单边带调制 单边带 SSB 调制技术 1 双边带简述 首先简述一下双边带调制 所谓双边带 DSB double sideband 调制 本质上就是调幅 时域上将基带信号x t 和高频载
  • pytorch FX模型静态量化

    文章目录 前言 一 pytorch静态量化 手动版 踩坑 二 使用FX量化 1 版本 2 代码如下 总结 前言 以前面文章写到的mobilenet图像分类为例 本文主要记录一下pytorchh训练后静态量化的过程 一 pytorch静态量化
  • 特征工程完全总结(Python源码)

    https www jianshu com p 114385e5a757
  • 【Linux】多线程的互斥与同步

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 线程冲突 二 重入与线程安全 1 线程不安全的情况 2
  • svg php,如何加载使用PHP生成的SVG文件?

    我想用 PHP创建一个SVG文件 然后将其包含在HTML文件中 这是我到目前为止 this tutorial之后 svg php header Content type image svg xml gt p gt http www w3 o
  • Session、Token、Cookie的区别及实际使用

    在现代Web开发中 身份验证和会话管理涉及一些基本概念 如Session Token和Cookie 尽管它们都用于管理不同方面的Web会话 但它们之间的差异是很重要的 在本文中 我们将一一介绍Session Token和Cookie的定义
  • 空间直角坐标系右手系和左手系的判定方法及绕轴旋转的正方向

    1 判定坐标系 右手大拇指指向z轴方向 其余四指由x轴握向y轴方向 如果成功 那么判定为右手系 左手大拇指指向z轴方向 其余四指由x轴握向y轴方向 如果成功 那么判定为左手系 坐标系的种类判断成功 那么接下来该判断旋转正方向 2 旋转正方向
  • Linux常用基本操作命令详解(一)

    Linux实用命令 1 前 言 2 常用Linux命令 2 1 常用的系统工作命令 2 2 系统状态检测命令 2 3 工作目录切换命令 3 小结 4 复习巩固题 参考资料 1 前 言 最近学习了有关Linux的一些常用基本命令 在此做个简单
  • python学习笔记 - 如何从几千个文件中寻找出指定的内容

    今天在处理数据时遇到这么个问题 如何从几千个txt文件中找到我想要的内容呢 这是我的实现思路 读取文件 选中指定的内容段 在新路径下保存内容段并命名为之前的文件名 以下是用python实现的代码 有详细注释 usr bin env pyth
  • Selenium Python 教程

    Selenium Python 教程 准备工作 元素定位 控制浏览器操作 Webelement常用方法 鼠标操作 键盘事件 获取断言信息 等待页面加载完成 隐式等待 在不同的窗口和框架之间移动 警告框处理 下拉框选择 文件上传 cookie
  • 网络安全(黑客)自学建议一一附学习路线

    温馨提示 为了避免误入歧途 自学请优先看 网络安全法 下面是一些学习建议 1 多请教有经验的人 切忌钻牛角尖 特别是刚入门的什么都不了解的情况下 可能你花好几天研究的一个东西 人10分钟就能搞定 一定不要做闷葫芦 有问题多问 遇到问题不可怕
  • 机器视觉第二次大作业

    内容 给定图像 消除其中的周期性干扰 以下为处理过程 1 显示图像的傅里叶变换后的频谱和傅里叶变换对数所得的频谱 从图2 可以明显的看出周期性噪声在频谱上的分布 于是在低中高频段上都有分布 但是低 通部分较少 所以考虑使用低通滤波器 此部分
  • java学习笔记13--反射机制与动态代理

    本文地址 http www cnblogs com archimedes p java study note13 html 转载请注明源地址 Java的反射机制 在Java运行时环境中 对于任意一个类 能否知道这个类有哪些属性和方法 对于任
  • StyleGAN2 解释

    本文是 1 的译文 按照作者Connor Shorten 的说法 此博客讨论的是StyleGAN2的诸如weight demodulation path length regularization和去掉progressive growing