news 2026/9/29 2:48:05

MMagic 中的 SinGAN 实战指南:单张自然图像的内部学习生成模型训练与推理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MMagic 中的 SinGAN 实战指南:单张自然图像的内部学习生成模型训练与推理
  • 媒体生成
  • 计算机视觉
  • 深度学习
  • 人工智能
  • 大模型

【免费下载链接】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.

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

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下载
SinGANballoons.png8ckpt 与 pkl 均可从 OpenMMLab 官方模型下载地址获取
SinGANfish-crop.jpg10ckpt 与 pkl 均可从 OpenMMLab 官方模型下载地址获取
SinGANbohemian.png10ckpt 与 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.

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

相关推荐

上一篇:Hermes Agent 多智能体协作完全指南:让一支智能体团队跑通你的复杂任务
下一篇:OpenSim Core:5个核心技术构建完整的生物力学模拟与分析平台

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 2:47:01

FileZilla Server 0.9.39 汉化绿色版部署与配置实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 2:46:55

大麦网抢票脚本保姆级教程:3步配置自动抢票

大麦网抢票脚本保姆级教程:3步配置自动抢票 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 手点"立即购买"总慢人一步?这个 大麦网抢票脚本 帮你把登录、查票、提…

作者头像 李华
网站建设 2026/9/29 2:46:47

MIPI LP RX调试全攻略:从协议到实战,解决没信号与花屏问题

1. 从一个“没信号”的调试现场说起如果你正在调试一块MIPI屏幕,上电后背光亮了、屏也热了,但画面就是黑的,示波器探头搭在LP信号线上却什么都抓不到,那你大概率已经踩进了MIPI LP RX这个坑里。LP,Low Power&#xff0…

作者头像 李华
网站建设 2026/9/29 2:46:28

工业级无人机调度平台开源架构实战:MAVLink+Celery+GeoHash

简介:这是一款面向工业级低空空域管理场景的开源无人机智能调度与管理平台,适用于无人机系统开发者、低空经济领域科研人员及电网、交通、城市安防等行业的技术实施团队,解决多机型协同调度、任务自动化执行与三维可视化管控等核心问题。资源…

作者头像 李华