SPADE 语义图像合成实战指南:从 GauGAN 原理到训练、测试与自定义数据集部署

  • 计算机视觉
  • 深度学习
  • 媒体生成
  • AI 应用

【免费下载链接】SPADE

Semantic Image Synthesis with SPADE

项目地址: https://gitcode.com/gh_mirrors/sp/SPADE
点击查看 免费下载

SPADE(Semantic Image Synthesis with Spatially-Adaptive Normalization,空间自适应归一化语义图像合成)是 NVIDIA 研究团队在 CVPR 2019 口头报告(Oral)中提出的语义图像合成方法,其核心思想是:将语义分割标签图(label map)作为条件输入,通过空间自适应归一化(Spatially-Adaptive Normalization) 替代传统生成模型中的全局归一化,从而在保留语义布局的同时生成高质量的真实感图像。本仓库(SPADE,即 GauGAN 的官方开源实现)提供了完整的训练、测试、数据预处理与自定义数据集支持。读完本文,你将掌握 SPADE 的核心原理、依赖安装、COCO-Stuff / ADE20K / Cityscapes 数据集准备、预训练模型推理、GauGAN 交互式生成、自定义数据集训练、多 GPU 并行、TensorBoard 日志以及 VAE 多模态生成等完整实战方案。

SPADE 方法示意图:左侧传统 Batch Norm 使用全局 γ/β,右侧 SPADE 依据语义分割图逐空间位置生成 γ/β

1. 什么是 SPADE:空间自适应归一化

SPADE 论文发表于 CVPR 2019(Oral),作者为 Taesung Park、Ming-Yu Liu、Ting-Chun Wang 和 Jun-Yan Zhu,论文标题为 Semantic Image Synthesis with Spatially-Adaptive Normalization。该工作发布后也被应用于 NVIDIA 的 GauGAN 交互式绘画应用:用户用色块草绘语义布局,系统即可生成对应真实感风景图像,如下图所示。

GauGAN 交互式绘画演示:左侧草绘语义标签,右侧实时生成真实感风景图像

SPADE 的核心组件是 SPADE 归一化模块,实现在 models/networks/normalization.py。其前向计算分为两步:

  1. 参数无关的归一化:先对激活值 x 施加 BatchNorm / InstanceNorm / SyncBatchNorm(不带仿射参数,affine=False);
  2. 语义条件调制:将语义分割图 segmap 用最近邻插值缩放到与激活值相同分辨率,经共享 MLP(mlp_shared,3×3 卷积 + ReLU,隐层通道数固定为 128)后,再由两个独立卷积分别输出逐空间位置的缩放因子 gamma 与偏移 beta,最终得到:
out = normalized * (1 + gamma) + beta

SPADE 的关键区别在于:传统 Batch Norm 的 γ/β 是逐通道的全局标量,而 SPADE 的 γ/β 是逐空间位置(pixel-wise)的调制图,直接由语义标签图卷积得到,因此归一化操作本身就能感知语义边界。这一设计避免了对齐损失(alignment issue):此前的方法(如 pix2pixHD)需要把语义布局压缩到深层特征图再上采样,容易丢失语义细节;SPADE 则让语义信息贯穿整个生成过程的每一层。

SPADE 模块通过 config_text 字符串配置,格式为 spade(norm)(ks),例如 spadesyncbatch3x3、spadeinstance5x5,其中 (norm) 指定参数无关归一化类型(syncbatch / batch / instance),(ks) 指定卷积核大小。代码中通过正则 spade(\D+)(\d)x\d 解析该配置(见 models/networks/normalization.py)。

2. 安装与环境要求

2.1 克隆与 Python 依赖

本仓库要求 PyTorch 1.0 及以上、Python 3 及以上。克隆仓库后安装依赖:

git clone https://github.com/NVlabs/SPADE.git
cd SPADE/
pip install -r requirements.txt

requirements.txt 内容如下:

torch>=1.0.0
torchvision
dominate>=2.3.1
dill
scikit-image

其中 dominate 用于生成可视化 HTML 页面,dill 用于选项对象的序列化保存(训练时 opt.pkl 的 pickle 存储),scikit-image 用于图像处理与保存。

2.2 安装 Synchronized-BatchNorm-PyTorch

SPADE 生成器默认使用同步批归一化(spectralspadesyncbatch3x3),因此需要同步批归一化的第三方实现。安装方式如下:

cd models/networks/
git clone https://github.com/vacancy/Synchronized-BatchNorm-PyTorch
cp -rf Synchronized-BatchNorm-PyTorch/sync_batchnorm .
cd ../../

安装后,models/networks/ 目录下应存在 sync_batchnorm 包,models/networks/normalization.py 中的 from models.networks.sync_batchnorm import SynchronizedBatchNorm2d 才能正常导入。

2.3 硬件要求

要复现论文中报告的结果,需要 NVIDIA DGX1 机器(8 块 V100 GPU)。日常调试或小规模训练可减少 GPU 数量,通过 --gpu_ids 指定。纯 CPU 推理可加 --gpu_ids -1。

3. 数据集准备

3.1 COCO-Stuff 数据集

COCO-Stuff 需要从 coco-stuff 官网 目录下仅放置了少量示例图片。需要下载的文件包括:

  • train2017.zip(训练图像)
  • val2017.zip(验证图像)
  • stuffthingmaps_trainval2017.zip(语义标签图)
  • annotations_trainval2017.zip(实例标注)

图像、标签与实例图必须按 datasets/coco_stuff 中已有的目录结构摆放,即:

datasets/coco_stuff/
├── train_img/      # 训练图像 jpg
├── train_inst/     # 训练实例图 png
├── train_label/    # 训练标签图 png
├── val_img/        # 验证图像 jpg
├── val_inst/       # 验证实例图 png
└── val_label/      # 验证标签图 png

COCO-Stuff 特别之处在于:论文使用了结合 "things 实例图边界" 与 "stuff 标签图" 的合成实例图。生成该实例图需要安装 pycocotools(pip install pycocotools),并运行仓库自带的脚本 datasets/coco_generate_instance_map.py 生成实例图。这也是 --dataset_mode coco 时数据加载器会自动设置 --contain_dontcare_label(标签图中含 255 号 don't-care 像素)的原因——COCO-Stuff 存在一个特殊的 "unknown" 标签(见 data/coco_dataset.py 中 modify_commandline_options 的自动设置)。

3.2 ADE20K 数据集

ADE20K 可下载 ADEChallengeData2016.zip(来自 MIT Scene Parsing Benchmark)。解压后,将 ADEChallengeData2016/images/ 下的 jpg 图像与 ADEChallengeData2016/annotations/ 下的 png 标签放入同一目录,目录结构同样对齐 datasets/coco_stuff 的 train_img/train_label/val_img/val_label 布局(ADE20K 无实例图,训练时需使用 --no_instance)。

3.3 图像加载模式(--preprocess_mode)

不同数据集可用不同的加载预处理方式,由 --preprocess_mode 配合 --load_size、--crop_size 控制。完整可选项定义在 options/base_options.py:

模式行为
resize_and_crop缩放到边长 load_size 的正方形,再随机裁剪到 crop_size
scale_width_and_crop缩放到宽为 load_size(高度按比例),再裁剪到 crop_size × crop_size 正方形
scale_shortside_and_crop将短边缩放到 load_size,再裁剪正方形
scale_width仅按宽度缩放,不裁剪
scale_shortside仅按短边缩放,不裁剪
crop直接随机裁剪
fixed固定按 crop_size 与 aspect_ratio 缩放
none不缩放,仅将宽高规整为 32 的倍数(__make_power_2)

预处理的核心逻辑在 data/base_dataset.py:get_params 根据模式计算裁剪位置与随机水平翻转,get_transform 据此组合 torchvision 变换流水线。训练阶段默认随机水平翻转做数据增强,可用 --no_flip 关闭。若要查看全部可用模式,可运行 python train.py --help。

4. 使用预训练模型生成图像

4.1 下载并解压预训练权重

从 Google Drive 文件夹下载 checkpoints.tar.gz,放到 checkpoints/ 目录并解压:

cd checkpoints
tar xvf checkpoints.tar.gz
cd ../

解压后 checkpoints/ 下应包含 coco_pretrained、ade20k_pretrained、cityscapes_pretrained 三个实验目录(分别对应三套预训练权重)。

4.2 运行推理

python test.py --name [type]_pretrained --dataset_mode [dataset] --dataroot [path_to_dataset]

参数说明:

  • [type]_pretrained:Step 1 解压出的 checkpoint 目录名,取值为 coco_pretrained、ade20k_pretrained 或 cityscapes_pretrained 之一;
  • [dataset]:coco、ade20k 或 cityscapes;
  • [path_to_dataset]:数据集根目录路径;
  • CPU 模式追加 --gpu_ids -1。

4.3 输出结果

输出图像默认存储在 ./results/[type]_pretrained/。从 test.py 可以看到,推理流程会调用 util/html.py 的 HTML 类生成一个汇总所有结果的网页(index.html),网页标题格式为 "Experiment = %s, Phase = %s, Epoch = %s"。直接用浏览器打开该 HTML 文件即可逐张查看语义输入(input_label)与合成图像(synthesized_image)的对比。

推理过程由 test.py 驱动:加载 Pix2PixModel 后调用 model(data_i, mode='inference'),内部在 torch.no_grad() 下执行前向生成(见 models/pix2pix_model.py)。

5. 使用 GauGAN 生成风景图像

论文与演示视频中展示了 GauGAN:一款交互式应用,用户通过绘制布局(如天空、山脉、水面、树木等色块)即可生成逼真的风景图像。GauGAN 模型使用从 Flickr 爬取的风景图像训练,NVIDIA 已发布具有相同功能的在线交互演示(NVIDIA AI Playground)。注意:GauGAN 风景模型的权重并未随本仓库发布,本仓库提供的是 COCO / ADE20K / Cityscapes 三个数据集的预训练权重。

6. 训练新模型

6.1 准备数据集并选择加载器

--dataset_mode 决定使用 BaseDataset 的哪个子类。数据加载器通过 data/init.py 中的 find_dataset_using_name 动态导入:data/{dataset_mode}_dataset.py 中与模式名匹配的类会被实例化,例如 facades 对应 data/facades_dataset.py 的 FacadesDataset,coco 对应 data/coco_dataset.py。

对自定义数据集,最简单的方式是使用 --dataset_mode custom(对应 data/custom_dataset.py),配合以下选项:

  • --label_dir [path_to_labels]:标签图目录;
  • --image_dir [path_to_images]:真实图像目录;
  • --label_nc [num_labels]:标签类别数量;
  • --contain_dontcare_label:标签图是否包含未知标签(dontcare = 255);
  • --no_instance:数据集无实例图时启用(不把实例边界作为额外输入通道)。

这些选项与 semantic_nc(生成器实际输入通道数)直接相关。在 options/base_options.py 中:

opt.semantic_nc = opt.label_nc + \
    (1 if opt.contain_dontcare_label else 0) + \
    (0 if opt.no_instance else 1)

即语义输入通道数 = 标签类别数 + don't-care 标签通道(如有)+ 实例边界通道(如无 --no_instance)。在 models/pix2pix_model.py 的 preprocess_input 中,标签图会被转为 one-hot 编码,若有实例图则通过 get_edges 提取实例边界图并与 one-hot 语义图拼接,共同作为生成器输入。

6.2 启动训练

# 训练 Facades 数据集
python train.py --name [experiment_name] --dataset_mode facades --dataroot [path_to_facades_dataset]

# 训练 COCO 数据集
python train.py --name [experiment_name] --dataset_mode coco --dataroot [path_to_coco_dataset]

# 训练自定义数据集
python train.py --name [experiment_name] --dataset_mode custom --label_dir [path_to_labels] --image_dir [path_to_images] --label_nc [num_labels]

注意 README 中自定义数据集的命令,--image_dir 与 --image_dir 前应确保没有多余空格,正确写法是 --image_dir [path_to_images]。

训练主循环位于 train.py:每个 epoch 遍历 DataLoader,按 --D_steps_per_G 交替更新生成器与判别器,并按 --save_latest_freq、--save_epoch_freq 保存 checkpoint。训练结束后按 --niter + --niter_decay 的节奏调整学习率。

6.3 常用训练选项

训练相关选项定义在 options/train_options.py,核心参数如下:

选项默认值说明
--niter / --niter_decay50 / 0固定学习率迭代数与线性衰减迭代数(总 epoch = 二者之和)
--lr0.0002Adam 初始学习率
--beta1 / --beta20.0 / 0.9Adam 动量项(TTUR 开启时默认 0.5/0.999)
--gan_modehinge对抗损失类型:ls / original / hinge
--netDmultiscale判别器结构:n_layers / multiscale / image
--lambda_feat10.0特征匹配损失权重(--no_ganFeat_loss 可关闭)
--lambda_vgg10.0VGG 感知损失权重(--no_vgg_loss 可关闭)
--D_steps_per_G1每个生成器步对应的判别器迭代次数
--tf_log关启用 TensorBoard 日志
--continue_train关从 latest checkpoint 继续训练

训练中采用 TTUR(Two Time-scale Update Rule):默认生成器学习率为 lr/2、判别器为 lr*2,加 --no_TTUR 后二者均为 lr(见 models/pix2pix_model.py 的 create_optimizers)。

6.4 多 GPU 与日志

  • GPU 选择:--gpu_ids 指定使用的 GPU,例如 --gpu_ids 0 用第一块,--gpu_ids 1,2 用第二、三块;-1 表示 CPU。batchSize 必须能整除 GPU 数量(见 options/base_options.py 的断言)。
  • TensorBoard 日志:加 --tf_log 后,日志存于 [checkpoints_dir]/[name]/logs,配合 TensorBoard 可实时查看损失曲线。也可通过 --display_freq(默认 100,屏幕显示频率)与 --print_freq(默认 100,控制台打印频率)控制可视化节奏;--no_html 可关闭中间结果网页保存。
  • 选项自动保存:训练开始时会把所有解析后的选项打印到控制台,并保存为 [checkpoints_dir]/[name]/opt.txt 与 opt.pkl,方便复现实验(见 options/base_options.py)。

6.5 完整选项列表

仓库中选项众多,部分只属于特定模型,部分默认值会随其他选项变化。BaseOptions 通过各类的静态方法 modify_commandline_options 动态加载与设置选项(机制见 options/base_options.py 的 gather_options,以及 models/networks/init.py)。例如:COCO-Stuff 含特殊 "unknown" 标签,data/coco_dataset.py 的 modify_commandline_options 会在 --dataset_mode coco 时自动设置 --contain_dontcare_label。完整选项可用 python train.py --help 查看。

7. 测试自定义训练模型

测试与预训练模型推理流程一致:

python test.py --name [name_of_experiment] --dataset_mode [dataset_mode] --dataroot [path_to_dataset]

测试相关选项定义在 options/test_options.py:

  • --results_dir:输出目录(默认 ./results/);
  • --how_many:最多生成的图像数量(默认无穷大,即处理完整个测试集);
  • --which_epoch:加载哪个 epoch 的 checkpoint(默认 latest)。

测试模式会自动启用 serial_batches(按顺序取 batch)、no_flip(不翻转)、phase=test,并将 preprocess_mode、crop_size、load_size 默认设为 scale_width_and_crop、256、256(见 options/test_options.py)。

8. 代码结构

仓库目录结构与职责(与 README 的 Code Structure 一节对应):

生成器结构速览

SPADEGenerator(models/networks/generator.py)以一系列 SPADEResnetBlock 构成:先将语义图下采样(或在使用 VAE 时从随机 z 出发),经过 head、middle、多个上采样 ResNet 块逐步恢复分辨率,最终经 LeakyReLU 与 tanh 输出 3 通道图像。--num_upsampling_layers 可选 normal / more / most:more 在两个中间 ResNet 块之间增加一次上采样,most 在生成器末端再增加一个上采样 + ResNet 块(对应输出分辨率更高)。

9. 使用 VAE 编码器实现风格控制与多模态输出

论文 Figure 15 展示了加入图像编码器的多模态输出能力:同一语义布局可生成多种风格/外观的合理图像。启用方式为训练与测试均加 --use_vae:

  • 训练时,模型除 netG(生成器)、netD(判别器)外还会创建 netE(图像编码器),并以 KL 散度损失 联合训练;
  • 生成时,从编码器得到的隐变量 z(或从标准正态采样)输入生成器,从而产生多样的输出。

相关实现:编码器 models/networks/encoder.py 输出 mu 与 logvar,经重参数化得到 z(见 models/pix2pix_model.py 的 encode_z 与 reparameterize);KL 损失由 models/networks/loss.py 中的 KLDLoss 计算,权重 --lambda_kld(默认 0.05)。启用 --use_vae 后,生成器的起点从「下采样语义图」切换为「线性层映射的随机向量」(见 models/networks/generator.py 与 models/networks/generator.py)。

10. 引用与许可

若你的研究使用了本代码,请引用论文:

@inproceedings{park2019SPADE,
  title={Semantic Image Synthesis with Spatially-Adaptive Normalization},
  author={Park, Taesung and Liu, Ming-Yu and Wang, Ting-Chun and Zhu, Jun-Yan},
  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},
  year={2019}
}

代码版权归 NVIDIA Corporation(2019)所有,采用 CC BY-NC-SA 4.0(署名-非商业性使用-相同方式共享 4.0 国际) 许可,仅供学术研究使用;商业使用或商务咨询请联系 NVIDIA。此外,本代码大量借鉴 pix2pixHD,并使用了 Jiayuan Mao 的同步批归一化实现,NVIDIA 团队对此表示感谢。

  • 计算机视觉
  • 深度学习
  • 媒体生成
  • AI 应用

【免费下载链接】SPADE

Semantic Image Synthesis with SPADE

项目地址: https://gitcode.com/gh_mirrors/sp/SPADE
点击查看 免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值