- 媒体生成
- 计算机视觉
- 深度学习
- 人工智能
- 大模型
【免费下载链接】mmagic
OpenMMLab Multimodal Advanced, Generative, and Intelligent Creation Toolbox. Unlock the magic 🪄: Generative-AI (AIGC), easy-to-use APIs, awsome model zoo, diffusion models, for text-to-image generation, image/video restoration/enhancement, etc.
SinGAN 是 ICCV'2019 提出的无条件生成模型,仅从一张自然图像即可学习图像的内部 patch 分布,进而生成保留全局结构、细节纹理且具有多样性的任意尺寸新样本。本文以 MMagic 仓库中 configs/singan/README.md 为核心,结合 mmagic/models/editors/singan 下的源码实现与 configs/singan 下的三套完整配置,系统讲解如何在 MMagic 中确定图像金字塔层数、理解配置文件每个参数、训练 SinGAN 以及通过 pickle 数据完成测试推理,帮助读者在内部学习(Internal Learning)这一任务上快速上手。
一、SinGAN 算法与 Internal Learning 任务
SinGAN 是 ICCV'2019 论文《Singan: Learning a Generative Model from a Single Natural Image》提出的无条件生成模型。与常见需要海量训练数据的 GAN 不同,它只使用一张自然图像完成训练,属于 MMagic 模型库中的 Internal Learning(内部学习)任务类别(见 configs/singan/metafile.yml 中Task: internal learning)。
其核心思路可概括为:
- 内部 patch 分布学习:模型被训练来捕获图像内部 patch 的分布,从而生成与输入图像携带相同视觉内容的高质量、多样化样本;
- 全卷积 GAN 金字塔:SinGAN 包含一个全卷积 GAN 金字塔,每一层负责学习图像在不同尺度上的 patch 分布,因此可以生成任意尺寸、任意宽高比的新样本;
- 保持全局结构、兼顾细粒度纹理:生成的样本既保持训练图像的全局结构,又拥有显著的多样性与精细纹理;
- 无条件、不限纹理图像:与之前的单图像 GAN 方案不同,SinGAN 不局限于纹理图像,并且是无条件的(直接从噪声生成样本,而非条件生成)。
论文中的用户研究表明,生成的样本经常被误认为是真实图像。SinGAN 被广泛用于一系列图像编辑任务。在 MMagic 中,SinGAN 的完整实现位于 mmagic/models/editors/singan/singan.py,其核心训练与推理逻辑都围绕"多尺度金字塔"展开。
二、MMagic 中的模型实现与架构原理
2.1 整体模型类:SinGAN
MMagic 中 SinGAN 模型类继承自BaseGAN,注册名为SinGAN(见 mmagic/models/editors/singan/singan.py)。其关键配置参数包括:
| 参数 | 含义 | 默认值 |
|---|---|---|
generator | 生成器配置或模型 | 必填 |
discriminator | 判别器配置或模型 | None |
generator_steps | 判别器更新前生成器的完整更新次数 | 1 |
discriminator_steps | 生成器更新前判别器的完整更新次数 | 1 |
num_scales | 生成器/判别器的尺度(stage)数量,从 0 开始计数,与原论文一致 | None |
iters_per_scale | 每个分辨率尺度上的训练迭代数 | 2000 |
noise_weight_init | 固定噪声的初始化权重 | 0.1 |
lr_scheduler_args | 学习率调度参数(使用 MultiStepLR,与原论文一致) | None |
test_pkl_data | 测试必需的 pickle 文件路径,内含固定噪声与噪声权重 | None |
从源码结构可以推断出训练流程的关键设计(singan.py 的train_step):
- 多分辨率渐进训练:每个分辨率(尺度)训练
iters_per_scale * discriminator_steps次后,curr_stage递增 1,并通过check_and_load_prev_weight从上一尺度加载权重; - 每尺度独立的优化器与调度器:
SinGANOptimWrapperConstructor会为每个尺度构造独立的生成器/判别器优化器,MMagic 明确要求 batch size 为 1 且不支持梯度累积; - 固定噪声与重建模式:
rand_mode='rand'从随机噪声采样,rand_mode='recon'使用固定噪声重建图像; - 噪声权重更新:每个尺度训练结束时,用当前尺度重建图像与下一尺度真实图像的 MSE 计算 RMSE,乘以
noise_weight_init作为下一尺度的噪声权重(singan.py)。
2.2 多尺度生成器与判别器
- 生成器:
SinGANMultiScaleGenerator(singan_generator.py)由num_scales + 1个GeneratorBlock组成。每个 block 为 5 层卷积(num_layers=5),基础通道数随尺度按2 ** floor(scale / 4)增长并封顶 128,输出激活为 Tanh,并带有残差连接(x + prev); - 判别器:
SinGANMultiScaleDiscriminator(singan_discriminator.py)同样按尺度堆叠DiscriminatorBlock,逐尺度判别; - 基础模块:
GeneratorBlock/DiscriminatorBlock的 head/body/tail 结构、BN 归一化与 LeakyReLU(0.2) 激活、权重初始化(Conv 使用normal_init(m, 0, 0.02))定义在 singan_modules.py。
2.3 损失函数
从 singan.py 的gen_loss与disc_loss可以看出,MMagic 的 SinGAN 采用:
- 生成器损失:WGAN 形式的对抗损失
-D(G(z)).mean(),叠加 10 倍权重的 MSE 重建损失10 * MSE(recon_img, real_img); - 判别器损失:WGAN 形式的
D(fake).mean() - D(real).mean(),并叠加 0.1 权重的梯度惩罚(gradient penalty)。
三、模型库与预训练权重
MMagic 官方在 configs/singan/metafile.yml 中登记了 3 个预训练 SinGAN 模型,对应关系如下(Num Scales从 0 开始计数,即金字塔层数):
| 模型 | 数据集 | Num Scales | 下载 |
|---|---|---|---|
| SinGAN | balloons.png | 8 | ckpt 与 pkl 均可从 OpenMMLab 官方模型下载地址获取 |
| SinGAN | fish-crop.jpg | 10 | ckpt 与 pkl 均可从 OpenMMLab 官方模型下载地址获取 |
| SinGAN | bohemian.png | 10 | ckpt 与 pkl 均可从 OpenMMLab 官方模型下载地址获取 |
其中 pkl 文件是测试必需的固定噪声与噪声权重数据,README 中明确提示其重要性。
四、训练前准备:确定图像金字塔层数 num_scales
原 README 特别强调:训练 SinGAN 前,应预先获取图像的尺度数量(stages)。该数值直接决定配置文件中生成器、判别器、训练迭代数的构造,是搭建配置文件的关键前置步骤。
获取方式如下(见 configs/singan/README.md):
>>> from mmgen.datasets.singan_dataset import create_real_pyramid >>> import mmcv >>> real = mmcv.imread('real_img_path') >>> _, _, num_scales = create_real_pyramid(real, min_size=25, max_size=300, scale_factor_init=0.75)注意:在 MMagic 中该函数已迁移至 mmagic/datasets/singan_dataset.py,实际导入语句为
from mmagic.datasets.singan_dataset import create_real_pyramid。
从源码看(singan_dataset.py),create_real_pyramid会根据min_size、max_size与scale_factor_init计算stop_scale(即金字塔层数),并逐层用mmcv.imrescale缩放生成reals图像金字塔列表。默认配置下(min_size=25, max_size=300, scale_factor_init=0.75):
num_scales即为配置文件中model.num_scales、生成器/判别器的num_scales,以及 pipeline 中real_scale0 ... real_scale{num_scales}键的数量;- 数据集
SinGANDataset在load_data_list中调用该函数,生成real_scale{i}系列键,并将input_sample初始化为与real_scale0同尺寸的零张量(singan_dataset.py); SinGANDataset.__len__默认返回int(1e6),配合batch_size=1与显式sampler=None使用。
五、配置文件全解
5.1 基础配置 singan_fish.py
configs/singan/singan_fish.py 是三套配置的基础文件,完整展示了 SinGAN 的所有配置要点:
_base_ = ['../_base_/gen_default_runtime.py'] # MODEL WRAPPER model_wrapper_cfg = dict(find_unused_parameters=True) # MODEL num_scales = 10 # start from zero generator_steps = 3 discriminator_steps = 3 iters_per_scale = 2000 # NOTE: add by user, e.g.: # test_pkl_data = ('./work_dirs/singan_fish/pickle/iter_66001.pkl') test_pkl_data = None model = dict( type='SinGAN', data_preprocessor=dict( type='DataPreprocessor', non_image_keys=['input_sample']), generator=dict( type='SinGANMultiScaleGenerator', in_channels=3, out_channels=3, num_scales=num_scales, ), discriminator=dict( type='SinGANMultiScaleDiscriminator', in_channels=3, num_scales=num_scales, ), noise_weight_init=0.1, test_pkl_data=test_pkl_data, lr_scheduler_args=dict(milestones=[1600], gamma=0.1), generator_steps=generator_steps, discriminator_steps=discriminator_steps, iters_per_scale=iters_per_scale, num_scales=num_scales) # DATA min_size = 25 max_size = 300 dataset_type = 'SinGANDataset' data_root = './data/singan/fish-crop.jpg' pipeline = [ dict( type='PackInputs', keys=[f'real_scale{i}' for i in range(num_scales)] + ['input_sample']) ] dataset = dict( type=dataset_type, data_root=data_root, min_size=min_size, max_size=max_size, scale_factor_init=0.75, pipeline=pipeline) train_dataloader = dict( batch_size=1, num_workers=0, dataset=dataset, sampler=None, persistent_workers=False) # TRAINING optim_wrapper = dict( constructor='SinGANOptimWrapperConstructor', generator=dict(optimizer=dict(type='Adam', lr=0.0005, betas=(0.5, 0.999))), discriminator=dict( optimizer=dict(type='Adam', lr=0.0005, betas=(0.5, 0.999)))) total_iters = (num_scales + 1) * iters_per_scale * discriminator_steps train_cfg = dict(max_iters=total_iters)关键参数说明:
num_scales:尺度数量,从 0 开始计数,需由create_real_pyramid预先算好(见第四节);generator_steps/discriminator_steps:均为 3,表示生成器与判别器各连续更新 3 次;iters_per_scale:每个尺度训练 2000 次迭代;total_iters:总迭代数 =(num_scales + 1) * iters_per_scale * discriminator_steps,即(10+1) * 2000 * 3 = 66000;noise_weight_init=0.1:固定噪声初始权重,训练中会按各尺度 RMSE 动态更新;lr_scheduler_args=dict(milestones=[1600], gamma=0.1):每个尺度内部使用 MultiStepLR,在第 1600 次迭代将学习率乘以 0.1;- 数据相关:
min_size=25、max_size=300、scale_factor_init=0.75,与金字塔构建命令保持一致;SinGANDataset只读取data_root指向的单张图像; - pipeline:
PackInputs打包real_scale0 ... real_scale9与input_sample共 11 个键; - 优化器:Adam,
lr=0.0005,betas=(0.5, 0.999),由SinGANOptimWrapperConstructor为每个尺度构造独立优化器; - 注意事项:SinGAN 不支持 val_loop 与 test_loop,配置文件显式设置
val_cfg = test_cfg = None、val_evaluator = test_evaluator = None,评估与生成需使用专用推理脚本(见第七节)。
5.2 继承配置:balloons 与 bohemian
- configs/singan/singan_balloons.py:
_base_ = ['./singan_fish.py'],仅将num_scales改为 8,data_root改为./data/singan/balloons.png,并通过model = dict(num_scales=num_scales, generator=dict(num_scales=num_scales), discriminator=dict(num_scales=num_scales), test_pkl_data=test_pkl_data)覆盖基类配置; - configs/singan/singan_bohemian.py:同样继承自
singan_fish.py,将max_size调整为 500,data_root改为./data/singan/bohemian.png,并重写custom_hooks中VisualizationHook的name='bohemian'。
两套继承配置均保留PickleDataHook(保存noise_weights、fixed_noises、curr_stage)与VisualizationHook(interval=5000、fixed_input=True)这两个自定义 hook。
5.3 custom_hooks 详解
custom_hooks = [ dict( type='PickleDataHook', output_dir='pickle', interval=-1, after_run=True, data_name_list=['noise_weights', 'fixed_noises', 'curr_stage']), dict( type='VisualizationHook', interval=5000, fixed_input=True, vis_kwargs_list=dict(type='SinGAN', name='fish')) ]PickleDataHook(实现见 mmagic/engine/hooks/pickle_data_hook.py):将模型的noise_weights、fixed_noises、curr_stage三个属性序列化为 numpy 后写入{work_dir}/pickle/iter_{iter+1}.pkl。interval=-1表示训练过程中不触发,after_run=True表示训练结束后保存一次。该 pkl 文件正是测试与推理所必需的固定噪声数据;VisualizationHook:每 5000 次迭代用固定输入可视化一次生成结果,便于观察各尺度的训练进展。
六、训练
在准备好单张图像数据(如./data/singan/fish-crop.jpg)并完成num_scales计算后,使用 MMagic 的标准训练入口即可启动训练:
python tools/train.py configs/singan/singan_fish.py多卡训练可使用 tools/dist_train.sh:
bash tools/dist_train.sh configs/singan/singan_fish.py 8训练结束后,PickleDataHook会在work_dirs/singan_fish/pickle/下生成形如iter_66001.pkl的 pickle 文件(文件名模板iter_{}.pkl,见 pickle_data_hook.py)。
七、测试与推理
7.1 为测试修改配置文件
原 README 明确指出:测试 SinGAN 模型时,必须修改配置文件并添加test_cfg。以 configs/singan/singan_balloons.py 为例,唯一需要做的就是把pkl数据的路径填入test_pkl_data:
test_cfg = dict( _delete_ = True pkl_data = 'path to pkl data' )在实际 MMagic 配置体系中,更推荐直接在model中设置test_pkl_data(配置文件顶部已预留注释示例):
# e.g. test_pkl_data = './work_dirs/singan_pkl/singan_balloons_20210406_191047-8fcd94cf.pkl' model = dict(test_pkl_data=test_pkl_data)从源码看,SinGAN.test_step会先调用load_test_pkl()(singan.py),从 pickle 中还原fixed_noises、noise_weights与curr_stage(_from_numpy会将 numpy 数据转回 Tensor 并搬到生成器所在设备),随后才执行生成。若未设置test_pkl_data,则测试无法进行——这是 SinGAN 与普通 GAN 最大的使用差异。
7.2 使用 demo 脚本生成样本
由于 SinGAN 不支持val_loop与test_loop,官方提供专用推理脚本 demo/singan_demo.py,用法如下:
python demo/singan_demo.py ${CONFIG_FILE} ${CHECKPOINT} \ [--samples-path ${SAMPLES_PATH}] \ [--save-prev-res] \ [--num-samples ${NUM_SAMPLES}]参数说明:
| 参数 | 作用 | 默认值 |
|---|---|---|
config | 配置文件路径(需已配置好test_pkl_data) | 必填 |
checkpoint | 训练得到的 ckpt 文件 | 必填 |
--seed | 随机种子 | 2021 |
--deterministic | 是否对 CUDNN 后端设置确定性选项 | 关闭 |
--samples-path | 生成图片的保存目录 | ./ |
--save-prev-res | 是否同时保存各中间尺度的生成结果(保存到stage{i}子目录) | 关闭 |
--num-samples | 生成的样本数量 | 10 |
脚本内部通过model.test_step(dict(inputs=dict(num_batches=1, get_prev_res=args.save_prev_res)))逐个生成样本(SinGAN 仅支持num_batches=1),生成结果经_tensor2img转回 uint8 图像后用mmcv.imwrite写出。
八、源码与测试验证
MMagic 为 SinGAN 提供了完整的单元测试,可作为理解实现与验证行为的参考:
- tests/test_models/test_editors/test_singan/test_singan.py:模型训练/推理流程测试;
- tests/test_models/test_editors/test_singan/test_singan_generator.py 与 test_singan_discriminator.py:生成器/判别器结构测试;
- tests/test_models/test_editors/test_singan/test_singan_modules.py:
GeneratorBlock/DiscriminatorBlock模块测试; - tests/test_datasets/test_singan_dataset.py:
create_real_pyramid与SinGANDataset测试; - tests/test_engine/test_optimizers/test_singan_optimizer_constructor.py:逐尺度优化器构造测试。
九、引用
若在研究中使用了 SinGAN,请引用原论文:
@inproceedings{shaham2019singan, title={Singan: Learning a generative model from a single natural image}, author={Shaham, Tamar Rott and Dekel, Tali and Michaeli, Tomer}, booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision}, pages={4570--4580}, year={2019}, }- 媒体生成
- 计算机视觉
- 深度学习
- 人工智能
- 大模型
【免费下载链接】mmagic
OpenMMLab Multimodal Advanced, Generative, and Intelligent Creation Toolbox. Unlock the magic 🪄: Generative-AI (AIGC), easy-to-use APIs, awsome model zoo, diffusion models, for text-to-image generation, image/video restoration/enhancement, etc.
相关推荐
SinGAN:从单张自然图像学习生成模型
SinGAN:从单张自然图像学习生成模型 项目介绍 SinGAN 是一个由 Tamar Rott Shaham、Tali Dekel 和 Tomer Micha
PaddleGAN SinGAN 实战指南:单张图片训练无条件生成模型,实现超分、图像编辑与静图转动
PaddleGAN SinGAN 实战指南:单张图片训练无条件生成模型,实现超分、图像编辑与静图转动 SinGAN(Single Image GAN)是 Pad
人工智能深度学习计算机视觉媒体生成视频处理图像处理MMagic 中 IndexNet 抠图模型实战指南:学习索引的图像 Matting 原理、配置解析与训练测试
MMagic 中 IndexNet 抠图模型实战指南:学习索引的图像 Matting 原理、配置解析与训练测试 导读 本文以 MMagic(OpenMMLab
媒体生成计算机视觉深度学习人工智能大模型
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考