一种基于样式的生成器架构,用于生成对抗性网络
Tero Karras (NVIDIA), Samuli Laine (NVIDIA), Timo Aila (NVIDIA)
http://stylegan.xyz/paper
摘要:我们借鉴风格转换文献,提出了一种用于生成对抗网络的替代生成器架构。新的架构会导致自动学习,无监督的高级属性分离 (例如, 在人脸上训练时的姿势和身份) 和生成的图像中的随机变化 (例如雀斑、头发), 并且使它可以直观地、特定规模的控制合成。新生成器在传统的分布质量指标方面改进了最先进的技术, 从而显著改善了插值特性, 并更好地消除了潜在的变异因素。为了量化插值质量和分离, 我们提出了两种新的自动化方法, 适用于任何生成器架构的自动化方法。最后, 我们介绍了一个新的, 高度多样化和高质量的人脸数据集。
系统要求
- 支持Linux和Windows,单出于性能和兼容性要求的考虑,官方建议使用Linux。
- 64位的Python3,建议使用Anaconda3,且numpy版本1.14.3或更新。
- 支持GPU的Tensorflow版本1.10.0或更新。
- 一个或多个具有至少11GB DRAM的高端NVIDIA GPU。官方推荐推荐配备8个Tesla V100 GPU的NVIDIA DGX-1。
- NVIDIA驱动版本391.35或更新,CUDA工具包9.0或更新,cuDNN7.3.1或更新。
这其中必须项有:
- NVIDIA GPU的电脑(硬件条件)
- NVIDIA驱动(驱动显卡)
- CUDA(NVIDIA并行计算框架),cuDNN是深度神经网络的加速库非必须
- GPU版的Tensorflow(深度学习框架)
下载运行模型的脚本
官方提供了StyleGan的GitHub地址,把代码下载下来进行解压本地目录下,同时你需要将目录路径添加到环境变量PYTHONPATH,为的是导入文件夹下的模块。
注意:变量名为PYTHONPATH,没有就新增一个,变量值为路径。
使用预训练网络
pretrained_example.py有给到使用预训练StyleGAN生成器的最小示例。执行脚本后会从谷歌网盘下载预训练StyleGAN生成器并生成一张图片,图片会在目录下的/results/example.png
看到。因为谷歌网盘的缘故我们无法直接下载,需要预训练模型的可以直接从这里下(提取码: 9vx8)。下载好的karras2019stylegan-ffhq-1024x1024.pkl
直接放到目录里就行。
直接在命令行下执行 python pretrained_example.py
,如果没有网络问题会见到下图的打印信息,这里我们直接下载好预训练生成器,所以代码需要改改,打开pretrained_example.py
改成下面这样,即把网络下载变成直接读取本地文件,并将原代码行注释。
# with dnnlib.util.open_url(url, cache_dir=config.cache_dir) as f:
with open('karras2019stylegan-ffhq-1024x1024.pkl', 'rb') as f:
_G, _D, Gs = pickle.load(f)
调整完之后只要我们运行pretrained_example.py
代码即可生成example.png
图片,如果你想生成其他随机图片的话只需要把5修改为其他数字即可:
rnd = np.random.RandomState(5)
generate_figures.py给出了一个更加高级的示例。这个脚本复制了论文中的图形,以说明样式混合、噪声输入和截断:
预先训练好的网络存储为标准的pickle文件在谷歌网盘上,同样的需要将脚本中dnnlib.util.open_url
函数改成直接读取pkl文件:
def load_Gs(file):
if file not in _Gs_cache:
with open(file, 'rb') as f:
_G, _D, Gs = pickle.load(f)
_Gs_cache[file] = Gs
return _Gs_cache[file]
main
主函数部分中的load_Gs
的参数调整为文件路径:
load_Gs('karras2019stylegan-ffhq-1024x1024.pkl')
下面的代码将会生成dnnlib.tflib.Network的3个实例。为了生成图像,您通常需要使用Gs—另外两个网络是完整的。为了让pickle.load()工作,你需要包含dnnlib
的源目录添加到环境变量PYTHONPATH中和tf.Session
设置为默认。可以通过调用dnnlib.tflib.init_tf()
初始化Session。
with open('karras2019stylegan-ffhq-1024x1024.pkl', 'rb') as f:
_G, _D, Gs = pickle.load(f)
# _G = Instantaneous snapshot of the generator. Mainly useful for resuming a previous training run.
# _D = Instantaneous snapshot of the discriminator. Mainly useful for resuming a previous training run.
# Gs = Long-term average of the generator. Yields higher-quality results than the instantaneous snapshot.
有三种方法使用预先训练的生成器:
- 使用
Gs.run()
进行输入和输出为numpy数组的快速模式操作:
# 选择特征向量
rnd = np.random.RandomState(5)
latents = rnd.randn(1, Gs.input_shape[1])
# 生成图像
fmt = dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True)
images = Gs.run(latents, None, truncation_psi=0.7, randomize_noise=True, output_transform=fmt)
第一个参数是一批形状为[num, 512]的特征向量,第二个参数预留给类别标签(StypeGan并没有使用,所以参数为None)。其余的关键字参数是可选的,可用于进一步修改操作(参见下面)。输出是一批图像,其格式由output_transform参数决定。
- 使用
Gs.get_output_for()
将生成器合并为一个更大的TensorFlow表达式的一部分:
latents = tf.random_normal([self.minibatch_per_gpu] + Gs_clone.input_shape[1:])
images = Gs_clone.get_output_for(latents, None, is_validation=True, randomize_noise=True)
images = tflib.convert_images_to_uint8(images)
result_expr.append(inception_clone.get_output_for(images))
前面的代码来自metrics/frechet_inception_distance.py。它生成一批随机图像,并将它们直接提供给Inception-v3网络,而无需在中间将数据转换为numpy数组。
- 查找
Gs.components.mapping
和Gs.components.synthesis
以访问生成器的各个子网络。与Gs
类似,子网络表示为dnnlib.tflib.Network
的独立实例:
src_latents = np.stack(np.random.RandomState(seed).randn(Gs.input_shape[1]) for seed in src_seeds)
src_dlatents = Gs.components.mapping.run(src_latents, None) # [seed, layer, component]
src_images = Gs.components.synthesis.run(src_dlatents, randomize_noise=False, **synthesis_kwargs)
上面的代码来自generate_figures.py。首先利用映射网络将一批特征向量转化为中间的W空间,然后利用合成网络将这些向量转化为一批图像。dlatents
数组为合成网络的每一层存储同一w向量的单独副本,以方便样式混合。
为训练准备数据集
训练和评估脚本对存储为多分辨率TFRecords的数据集进行操作。每个数据集都由一个目录表示,其中包含几个分辨率相同的图像数据,以支持有效的流。还有一个每个分辨率单独的*.tfrecords文件,如果数据集包含标签,它们也存储在单独的文件中。默认情况下,脚本期望在datasets/
中找到数据集。可以通过编辑config.py
来更改目录:
result_dir = 'results' # 结果目录
data_dir = 'datasets' # 数据目录
cache_dir = 'cache' # 缓存目录
训练网络
设置好数据集后,你就可以训练你自己的StyleGAN网络:
- 编辑train.py,通过取消注释或编辑特定行来指定数据集和训练配置。
- 使用
python train.py
来运行训练脚本。 - 结果被写入一个新创建的目录
results/
。- - 训练可能需要几天(或几周)才能完成,这取决于机器配置。
使用Tesla V100 GPU的默认配置的预计培训时间:
GPU | 1024×1024 | 512×512 | 256×256 |
---|---|---|---|
1 | 41 天 4小时 | 24 天 21 小时 | 14 天 22 小时 |
2 | 21 天 22 小时 | 13 天 7 小时 | 9 天 5 小时 |
4 | 11 天 8 小时 | 7 天 0 小时 | 4 天 21 小时 |
8 | 6 天 14 小时 | 4 天 10 小时 | 3 天 8 小时 |
评估质量和分解
使用run_metrics.py
可以评估本文中使用的质量和解纠缠度量。默认情况下,脚本将计算预训练的FFHQ生成器的Frechet初始距离(fid50k),并将结果写入results下新创建的目录。可以通过取消注释或编辑run_metrics.py
中的特定行来更改确切的行为。使用Tesla V100 GPU预训练的FFHQ生成器的预期评估时间和结果:
度量 | 时间 | 结果 | 描述 |
---|---|---|---|
fid50k | 16 分钟 | 4.4159 | Fréchet Inception Distanc使用50,000张图像。 |
ppl_zfull | 55 分钟 | 664.8854 | Z 中完整路径的感知路径长度。 |
ppl_wfull | 55 分钟 | 233.3059 | W 中完整路径的感知路径长度。 |
ppl_zend | 55 分钟 | 666.1057 | Z 中路径端点的感知路径长度。 |
ppl_wend | 55 分钟 | 197.2266 | W 中路径端点的感知路径长度 |
ls | 10 hours | z: 165.0106 w: 3.7447 |
Z 和 W中的线性可分性。 |
请注意,由于TensorFlow的非确定性,每次运行的确切结果可能有所不同。
其他预训练网络生成的图片
项目地址:https://github.com/NVlabs/stylegan