StyleGAN2 Encoder使用18x512的dlatents进行迭代优化,实现对目标图片的“无限逼近”并重建高质量图像,保存对应的dlatents用于后续处理。
获取StyleGAN2 Encoder,GitHub上的链接是:
https://github.com/rolux/stylegan2encoder
StyleGAN2 Encoder改写了StyleGAN2的projector.py,增加了project_images.py,其实现的效果要优于StyleGAN2自带的run_projector.py。
StyleGAN2 Encoder的底层依然依赖于StyleGAN2核心的G_main类(生成器)、G_mapping类(映射网络)、G_synthesis_stylegan2类(合成网络)、D_stylegan2类(辨别器)等,这些类的源代码可以查看:./training/networks_stylegan2.py。
在训练过程中,通过对dlatent_avg(dlatent_avg是W空间dlatents向量(18x512)的平均值)进行预测和更新来实现输入的迭代,并且在每次迭代过程中引入噪声,即:迭代的输入 = 迭代的dlatent_avg + 噪声;同时,学习率也在每步迭代过程中进行更改;将迭代的输入通过StyleGAN2网络生成预测图像,再利用VGG16网络计算预测图像和目标图像之间的loss。
在训练的开始,StyleGAN2随机产生10000个向量,并用它们的平均值作为训练的起点,简化了训练过程。
StyleGAN2没有使用tensorflow自带的方法,而是使用dnnlib.tflib来构建优化函数。dnnlib.tflib是英伟达团队在tensorflow上构建的一组库函数,以便于代码维护,也有助于理解代码结构。
为解决StyleGAN存在的伪影(artifacts)问题,StyleGAN2对StyleGAN的合成网络进行了修改,如下图所示:
其中,(a)是StyleGAN的合成网络,(b)是StyleGAN的实现细节;(c)是StyleGAN2的合成网络,(d)是StyleGAN2的实现细节,其具体说明以及改动的原因,可以查看StyleGAN2的论文:
论文地址:https://arxiv.org/pdf/1912.04958.pdf
总体上,StyleGAN2 Encoder基于真实人脸图片重建高质量、可操控的人脸图像,较之第一代StyleGAN Encoder效果更好,但同样的GPU条件下(比如:NVIDIA GeForce RTX 2080Ti)运行时间更长。
我们花时间研究了一下StyleGAN2 Encoder的projector.py和project_images.py的源代码,其整体代码结构如下图所示,其中浅绿色部分为projector.py,白色部分为project_images.py:
具体的源代码(含中文注释)如下:
projector.py
import numpy as np
import tensorflow as tf
import dnnlib
import dnnlib.tflib as tflib
from training import misc
#----------------------------------------------------------------------------
class Projector:
def __init__(self,
# 初始化变量
# vgg16_pkl = 'https://drive.google.com/uc?id=1N2-m9qszOeVC9Tq77WxsLnuWwOedQiD2',
vgg16_pkl= '.\models\\vgg16_zhang_perceptual.pkl',
num_steps = 1000,
initial_learning_rate = 0.1,
initial_noise_factor = 0.05,
verbose = False
):
self.vgg16_pkl = vgg16_pkl
self.num_steps = num_steps
self.dlatent_avg_samples = 10000
self.initial_learning_rate = initial_learning_rate
self.initial_noise_factor = initial_noise_factor
self.lr_rampdown_length = 0.25
self.lr_rampup_length = 0.05
self.noise_ramp_length = 0.75
self.regularize_noise_weight = 1e5
self.verbose = verbose
self.clone_net = True
self._Gs = None
self._minibatch_size = None
self._dlatent_avg = None
self._dlatent_std = None
self._noise_vars = None
self._noise_init_op = None
self._noise_normalize_op = None
self._dlatents_var = None
self._noise_in = None
self._dlatents_expr = None
self._images_expr = None
self._target_images_var = None
self._lpips = None
self._dist = None
self._loss = None
self._reg_sizes = None
self._lrate_in = None
self._opt = None
self._opt_step = None
self._cur_step = None
# 显示信息
def _info(self, *args):
if self.verbose:
print('Projector:', *args)
# 设置StyleGAN网络
def set_network(self, Gs, minibatch_size=1):
assert minibatch_size =&#