【PyTorch项目实战】CycleGAN:无需成对训练样本,支持跨领域图像风格迁移

发布于:2025-06-23 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、风格迁移模型🎨

1、发展时间线

年份 模型/方法 发布者/会议 技术关键词 关键贡献或备注
2015 NeuralStyleTransfer Gatys等(CVPR) Gram矩阵、VGG特征、优化迭代 开创性风格迁移方法,掀起研究热潮
2016 FastStyleTransfer Johnson等(ECCV) 感知损失、快速前向网络 实现实时风格迁移,提升实用性
2017 AdaIN Huang等(NeurIPS) 自适应实例归一化 任意风格迁移新范式,灵活性强
2017 WCT Li等(CVPR) 白化与着色变换(WCT) 无需训练,基于特征统计
2017 Pix2Pix Isola等(CVPR) 条件GAN、成对图像翻译 开创成对图像翻译标准方法
2017 CycleGAN Zhu等(ICCV) 循环一致性、无监督图像翻译 打破成对限制,支持任意风格迁移
2018 MUNIT Huang等(ECCV) 多模态风格迁移、潜变量解耦 实现多风格切换
2019 UGATIT Kim等(ICLR) 注意力机制、可控无监督迁移 强化结构保持,适用于面部、插画等
2020 CUT Park等(ECCV) 对比学习、PatchNCE损失 改进CycleGAN,提升图像结构保持能力
2022 StableDiffusion CompVis等 文图扩散模型、文本控制 图文创作与艺术风格迁移
2023 DALL·E2 OpenAI CLIP引导图文生成、多模态优化 多样化风格图生成利器,适合设计类应用

MUNIT:多模态无监督图像到图像翻译 —— https://github.com/nvlabs/MUNIT
在这里插入图片描述

2、分类与优缺点

类别 代表模型 特点描述 优点 局限性
统计特征匹配类 NeuralStyleTransfer、AdaIN、WCT 特征层统计参数(均值/方差)匹配 快速、无需训练、可实时应用 风格粒度不可控,结构保持差
成对监督类 Pix2Pix 条件GAN训练,有明确输入输出成对 精确控制、结构保持好 需成对样本,任务限制大
无监督图像翻译类 CycleGAN、DualGAN、CUT 循环一致性、对比学习等实现非配对迁移 无需配对,适用于多风格切换 训练稳定性差,细节模糊,存在模式崩溃风险
结构保持增强类 UGATIT、MUNIT、DRIT 引入注意力或语义模块,增强结构和可控性 支持局部显著风格、结构更完整 推理慢,训练复杂,对参数敏感
跨模态生成类 StableDiffusion、DALL·E、ControlNet 文本控制图像风格,生成类大模型 控制力强、创意表达能力强 结构不可控、不适用于精确图像风格迁移

3、选择建议

使用需求 推荐模型 是否需训练 推理速度 结构保持 风格质量 适用建议
快速预览风格效果 AdaIN、WCT ★★★★★ ★★ ★★★★ 适合滤镜类APP、快速尝试多种风格
批量生成某一固定风格 FastStyleTransfer ★★★★ ★★★★ ★★★★ 一次训练后多图高效渲染
精确图↔图风格转换 Pix2Pix ★★★ ★★★★★ ★★★★ 数据成对充分时优选
任意图像风格迁移 CycleGAN、CUT ★★★ ★★★★ ★★★★ 适合插画↔实拍等风格转换
多风格自由切换 MUNIT、DRIT、StyleGAN ★★ ★★★★ ★★★★ 风格交互应用场景,如头像生成、社交内容等
文本描述控制图像风格 StableDiffusion、DALL·E ★★ ★★ ★★★★★ 创意类内容创作,如封面设计、艺术生成等

4、HuggingFace Demo(instruct-pix2pix) —— 在线测试

https://huggingface.co/spaces/timbrooks/instruct-pix2pix

  • 输入:任意照片 + 文字指令(如 “Turn it into a cyberpunk style”)
  • 特点:无需风格图,直接通过文本描述控制风格。
  • 超参数:
    • Text CFG:7.5(默认)
    • Image CFG:1.5(默认)
    • 备注:权重越大,越倾向于哪一方!
  • 输入图像的一般要求
    • 格式:常见的图片格式(如 .jpg, .png, .webp)。
    • 分辨率:建议 512x512 ~ 1024x1024 像素(太高可能被自动压缩)。
    • 内容清晰:避免过度模糊、噪点或强压缩伪影。
    • 主体明确:风格迁移对主体(如人像、建筑、风景)效果更好。

二、论文简读

(1)FastStyleTransfer(快速风格迁移,Johnson et al., 2016)

快速神经风格:将一张图片的内容与另一张图片的风格进行混合

在这里插入图片描述

1、原理概述

FastStyleTransfer 是一种利用感知损失(Perceptual Loss)实现的快速图像风格迁移方法。其基本结构为一个前馈神经网络,在训练阶段学习将任意图像转换为特定风格的图像。训练完成后,该网络在推理阶段可实现毫秒级图像风格转换。

网络结构

  • 输入:内容图像(如渲染图);
  • 输出:风格化图像;
  • 损失函数基于 VGG 特征提取器:
    • 内容损失:保持原始图像的语义结构;
    • 风格损失:匹配目标风格图的Gram矩阵特征;
    • 总变差损失(TV loss):增强图像平滑性。

2、特点与优势

优势点 说明
✅ 推理速度快 一次前向传播即可完成风格迁移,0.05~0.2秒/张,适合实时应用。
✅ 不改变图像结构 网络学习内容保留与风格分离,结果结构清晰。
✅ 工程部署简单 可导出为TorchScript或ONNX,部署于边缘设备或网页端。

3、 局限性

局限点 描述
❌ 每种风格需单独训练一个模型 若需支持多种风格,需为每种风格图单独训练一次,增加存储与训练成本。
❌ 风格灵活性较低 风格结果相对固定,无法在推理阶段动态调整风格程度或更换风格图像。

(2)AdaIN(自适应实例规范化,Huang & Belongie, 2017)

AdaIN:通过自适应实例规范化,实现实时任意风格转换

在这里插入图片描述

1、原理概述

AdaIN 是一种任意风格图像迁移方法,通过在推理阶段动态注入风格图像特征统计信息,实现任意风格的实时转换。核心思想是:将内容图像的特征归一化后,重新赋予目标风格图的均值与方差,从而在不改变内容结构的前提下完成风格映射。

关键模块:Adaptive Instance Normalization
设内容特征为 fc,风格特征为 fs,则:
AdaIN ( f c , f s ) = σ ( f s ) ⋅ ( f c − μ ( f c ) σ ( f c ) ) + μ ( f s ) \text{AdaIN}(f_c, f_s) = \sigma(f_s) \cdot \left( \frac{f_c - \mu(f_c)}{\sigma(f_c)} \right) + \mu(f_s) AdaIN(fc,fs)=σ(fs)(σ(fc)fcμ(fc))+μ(fs)
其中:
μ:均值
σ:标准差

2、特点与优势

局限点 描述
❌ 风格仅体现颜色与纹理分布 不适合高度结构化或抽象风格(如某些插画或2.5D卡通),表现不如GAN类方法。
❌ 对抗性质量不及GAN 相比CycleGAN等对抗训练方法,输出真实感稍弱,细节较平滑。

3、局限性

局限点 描述
❌ 风格仅体现颜色与纹理分布 不适合高度结构化或抽象风格(如某些插画或2.5D卡通),表现不如GAN类方法。
❌ 对抗性质量不及GAN 相比CycleGAN等对抗训练方法,输出真实感稍弱,细节较平滑。

(3)CycleGAN:基于循环一致性的无配对图像风格迁移方法(Zhu et al., 2017)

在这里插入图片描述

1、原理概述

CycleGAN是一种用于图像到图像转换(Image-to-Image Translation)任务的生成对抗网络(GAN)框架,具有无需成对训练样本,学习两个域之间的映射关系,实现跨领域图像转换。其核心思想是通过循环一致性损失(Cycle Consistency Loss) 约束风格迁移的可逆性,从而在保留图像结构的同时实现风格映射。

基本架构:CycleGAN包括两个生成器(GA→B 和 GB→A)与两个判别器(DA 和 DB
其中:

  • GA→B:将A域图像(如照片)转换为B域图像(如油画);例如:照片 → 油画、夏天 → 冬天、马 → 斑马
  • GB→A:实现B→A的反向转换;例如:照片 → 油画、夏天 → 冬天、马 → 斑马(反着)
  • DA 与 DB:分别判别生成图像是否属于对应域的真实样本。

循环一致性损失(Cycle Loss)

  • A → B → A ≈ A
  • B → A → B ≈ B

这种结构使得即使两个领域之间没有一一对应的图像对,模型也能学到结构稳定的风格映射。

2、特点与优势

优势点 说明
✅ 无需配对训练样本 相较于Pix2Pix等方法,CycleGAN仅依赖两个领域的非配对图像,降低了数据准备难度。
✅ 结构保持能力强 通过循环损失保持图像内容结构不变,适合结构稳定但风格差异大的任务(如风景↔油画)。
✅ 具备双向映射能力 同时学习A→B和B→A转换路径,提升模型鲁棒性与泛化能力。
✅ 可生成较高质量图像 相比简单风格迁移模型,CycleGAN在图像真实感、边缘保留等方面表现更优。

3、局限性

局限点 描述
❌ 需大量非配对数据 虽不要求成对图像,但仍需大量覆盖多样风格的两域图像(例如上千张A域图像+上千张B域图像)才能训练有效模型。
❌ 单图像训练效果差 如果仅提供一张风格图像,模型难以提取稳定风格特征,易过拟合或风格失真。
❌ 推理依赖训练域 测试时输入图像必须来自训练时分布相近的领域,否则模型输出不可控、泛化能力弱。
❌ 训练耗时且资源密集 通常需数小时至数天GPU训练时间,不适合快速测试或小样本部署。

4、适用与非适用场景

✅ 适用场景

  • 领域之间存在明显风格差异,但结构内容一致(如:实拍照片↔渲染图、风景↔油画)。
  • 具备大规模非配对训练数据,可以覆盖目标领域的主要特征分布。
  • 需要高质量风格映射效果,用于研究、艺术生成等精度要求较高任务。

❌ 非适用场景

  • 仅有1~5张风格参考图像,无法支撑有效训练。
  • 风格域差异较抽象或领域跨度过大(如素描↔动漫、照片↔2.5D手绘)时,CycleGAN输出容易失控。
  • 对训练时长、部署资源有限制,如实时应用、比赛时间紧张等场合。

5、实战建议

在如 “ 渲染图↔2.5D插画风格 ” 的图像风格互换场景中,若仅有少量参考图或时间限制较大,建议优先采用无需训练的通用风格迁移方法(如AdaIN或FastStyleTransfer)。而CycleGAN更适用于训练资源充足、可离线生成高质量双向风格映射的情况。

三、CycleGAN:项目实战

1、环境配置

conda create -n CycleGAN38 python=3.8 -y
conda activate CycleGAN38
pip install requirements.txt

2、使用CPU模式而非GPU(默认强制使用,有GPU跳过该步骤)

(模型强制使用GPU)如果你没有 GPU 或者 CUDA 配置不正确,可以修改代码以强制使用 CPU:

(1)在 base_options.py 文件中

torch.cuda.set_device(opt.gpu_ids[0])
######################################################1)将其修改为:
######################################################
# 如果没有 GPU,可直接强制使用 CPU
if torch.cuda.is_available() and len(opt.gpu_ids) > 0:
    torch.cuda.set_device(opt.gpu_ids[0])
else:
    device = torch.device("cpu")  # 强制使用 CPU
    print("No GPU detected, using CPU instead.")


# state_dict = torch.load(load_path, map_location=str(self.device))
######################################################2)将其修改为:
######################################################
if self.device.type == 'cpu':
    state_dict = torch.load(load_path, map_location=lambda storage, loc: storage)
else:
    state_dict = torch.load(load_path, map_location=self.device)

(2)在 base_options.py 文件中

self.device = torch.device('cuda:{}'.format(self.gpu_ids[0])) if self.gpu_ids else torch.device('cpu')  # get device name: CPU or GPU
######################################################
将其修改为:
######################################################
# self.device = torch.device('cuda:{}'.format(self.gpu_ids[0])) if self.gpu_ids and self.gpu_ids[0] != -1 else torch.device('cpu')
if self.gpu_ids and self.gpu_ids[0] != -1 and torch.cuda.is_available(): # 增加了 torch.cuda.is_available() 的检查
     self.device = torch.device('cuda:{}'.format(self.gpu_ids[0]))
else: # 如果没有指定有效 GPU 或 CUDA 不可用,则强制使用 CPU
     self.device = torch.device('cpu')

(3)在 networks.py 文件中

def init_net(net, init_type='normal', init_gain=0.02, gpu_ids=[]):
    # if len(gpu_ids) > 0:
    #     assert(torch.cuda.is_available())
    #     net.to(gpu_ids[0])
    #     net = torch.nn.DataParallel(net, gpu_ids)  # multi-GPUs
    # init_weights(net, init_type, init_gain=init_gain)
    # return net
	######################################################
	将其修改为:
	######################################################
    # Determine the device
    if len(gpu_ids) > 0 and gpu_ids[0] != -1 and torch.cuda.is_available(): # 修改了这里的条件判断
        device = torch.device('cuda:{}'.format(gpu_ids[0]))
        net.to(device)
        if len(gpu_ids) > 1: # Only use DataParallel if multiple GPUs are specified
             net = torch.nn.DataParallel(net, gpu_ids)  # multi-GPUs
    else: # 增加了 else 分支来处理 CPU 情况
        device = torch.device('cpu')
        net.to(device)

    init_weights(net, init_type, init_gain=init_gain)
    return net

3、文件配置

地址:Index of /cyclegan
在这里插入图片描述

github中提供的下载教程:
在这里插入图片描述
bash是linux命令;
(1)在windows系统中,使用记事本打开文件pytorch-CycleGAN-and-pix2pix/datasets/download_pix2pix_dataset.sh;
(2)定位URL,打开http://efrosgans.eecs.berkeley.edu/cyclegan/datasets/;
(3)下载数据集ae_photos.zip,并解压到pytorch-CycleGAN-and-pix2pix/datasets文件夹下;

(1)数据集下载

cyclegan地址:http://efrosgans.eecs.berkeley.edu/cyclegan/datasets/

(2)模型下载

cyclegan地址:http://efrosgans.eecs.berkeley.edu/cyclegan/pretrained_models/

4、代码测试(Test a CycleGAN model)

以下是两条test.py命令的参数逐项详细解析(详细请看test.py说明),用于在复现CycleGAN模型时正确理解和自定义测试流程:

✅ 命令1:双向测试 CycleGAN(A→B和B→A)
python test.py --dataroot ./datasets/maps --name maps_cyclegan --model cycle_gan
    参数	含义
	--dataroot ./datasets/maps	指定数据集根目录,CycleGAN会自动寻找testA/和testB/两个子目录,分别代表两个方向的测试数据
	--name maps_cyclegan	模型名称,对应于checkpoints/maps_cyclegan路径下保存的训练模型参数(G_A、G_B等)
	--model cycle_gan	指定模型类型为cycle_gan,表示使用CycleGAN的生成器G_A(A→B)和G_B(B→A)做双向翻译测试

✅ 命令2:仅单向测试(如horse→zebra)
python test.py --dataroot datasets/horse2zebra/testA --name horse2zebra_pretrained --model test --no_dropout
    参数	含义
	--dataroot datasets/horse2zebra/testA	测试集只提供testA/(源域图像),不需要testB/,只做单向A→B映射
	--name horse2zebra_pretrained	指定模型名为horse2zebra_pretrained,将从checkpoints/horse2zebra_pretrained中加载训练好的G_A模型
	--model test	指定测试模式为单向测试,默认只使用G_A(源域→目标域),不会进行Cycle Consistency或B→A映射
	--no_dropout	禁用Dropout(测试阶段通常不使用Dropout,结果更加稳定)

📁 输出文件默认保存路径:./results/horse2zebra_pretrained/test_latest/images/

备注1:CycleGAN 本质上无法保证 " 主体不变、仅变风格 "

CycleGAN 所使用的是无监督图像到图像转换框架,其本质是:在不使用成对图像监督的前提下,学习两个域之间的整体映射关系,而不是单独控制前景或背景。

备注2:白 / 黑背景将使得模型失去迁移方向

原因如下:

  • CycleGAN不具备语义理解能力
    它依靠像素分布的统计特征进行映射;
    全白/黑背景的统计特征过于简单,模型难以提取有用信息;
    如果背景占图像面积过大,模型会将背景视作主体的一部分。
  • 背景过于“干净”,扰乱迁移逻辑
    模型的迁移逻辑通常依赖局部纹理;
    纯背景导致输入特征“太干净”,而输出风格域中的背景往往存在纹理或渐变,模型会“强行添加内容”;
  • 目标结构稀疏,易丢失原图语义
    CycleGAN 的生成器为全卷积结构,弱语义感知;
    当前景小、背景大时,模型会偏向“迁移背景”,导致主题模糊。

对于CycleGAN:

  • 白/黑背景不是“无内容”,而是“全是背景内容”;
  • 如果风格图中的背景有丰富纹理或颜色变化,模型会认为“纯白纯黑背景是待转换的区域”;
  • 最终结果:模型在尝试改变背景的过程中,牺牲了前景稳定性,迁移效果不佳。

网站公告

今日签到

点亮在社区的每一天
去签到