Go Back
CycleGAN pix2pix 风格迁移 深度学习 计算机视觉

CycleGAN & pix2pix — 项目复现、浮世绘风格迁移与改进总结

最后编辑: 2026-05-31 16:57

一、项目概述

本项目基于 pytorch-CycleGAN-and-pix2pix 框架,围绕图像到图像翻译(Image-to-Image Translation)进行了三个阶段的探索:

阶段内容状态
复现CycleGAN (maps) + pix2pix (facades) 标准数据集训练与测试✅ 完成
风格迁移浮世绘(ukiyo-e)风格迁移:CycleGAN 在风景照↔浮世绘数据上的完整 40 epoch 训练✅ 完成
改进自注意力生成器 + AE 判别器 + LPIPS 感知损失的方案设计与代码修正✅ 完成(设计阶段)

仓库地址:seraphim522/pytorch-CycleGAN-and-pix2pix_re(复现 fork)


二、框架理解

该项目的核心设计是 统一训练骨架 + 动态装配机制

•••
train.py → 解析参数 → 动态加载模型(models/) + 数据集(data/)
         → 训练循环(不关心具体模型类型)

关键设计点

  • 模型工厂 models/ __init__.py:根据 --model cycle_gan 自动导入对应模块
  • 数据集工厂 data/ __init__.py:根据 --dataset_mode unaligned 自动选择数据加载器
  • 参数双向修改:模型和数据集可以修改命令行默认值(如 pix2pix 默认使用 aligned 数据集)
  • 统一基类 BaseModel:所有模型通过 set_inputforwardoptimize_parameters 接口统一

核心网络组件(models/networks.py

组件默认架构用途
Generatorresnet_9blocks / unet_256图像生成
Discriminatorbasic(70×70 PatchGAN)真假判别
GAN Losslsgan / vanilla / wgangp对抗损失
归一化InstanceNorm(CycleGAN)/ BatchNorm(pix2pix)特征归一化

CycleGAN 原理

CycleGAN 实现 无配对 图像翻译,核心是 循环一致性

•••
real_A ─→ G_A ─→ fake_B ─→ D_A(对抗损失)
                       └─→ G_B ─→ rec_A ≈ real_A(循环损失)
real_A ─→ G_B ─→ idt_B ≈ real_A(恒等损失)

训练 4 个网络(G_A, G_B, D_A, D_B),3 类损失协同工作。


三、复现实验

3.1 CycleGAN — maps 数据集

  • 数据集:maps(航拍图↔地图),无配对
  • 训练:30 epoch,单卡 RTX 3060(6GB)
  • 结果:成功完成训练与测试,生成器有效学习域间翻译

3.2 pix2pix — facades 数据集

  • 数据集:facades(建筑标签↔照片),配对
  • 模式:使用预训练模型 facades_label2photo_pretrained 测试
  • 结果unet_256 生成器(54.4M 参数),成功完成标签→照片的翻译

3.3 环境问题修复

  • Windows 下 .sh 脚本换行符 \r 兼容:find . -name '*.sh' -exec sed -i 's/\r//' {} \;

四、浮世绘风格迁移

4.1 数据集

集合来源数量
trainA真实风景照片6,290 张
trainB浮世绘(ukiyo-e)画作562 张
testA/testB对应测试集752 / 263 张

特点:trainB 仅 562 张,风格多样性受限,CycleGAN 无配对机制仍有效。

4.2 训练配置

参数说明
生成器ResNet-9blocks~11M 参数
判别器PatchGAN (70×70)~2.7M 参数
GAN 模式LSGAN最小二乘损失
循环损失权重λ_A = λ_B = 10.0L1 逐像素
Identity 权重0.5颜色保持
Epoch40(20 恒定 lr + 20 线性衰减)总耗时 6h44min
Batch size16GB VRAM 限制

4.3 训练结果

损失起始值最终值改善
cycle_A(照片→浮世绘→照片)2.501.55↓38%
cycle_B(浮世绘→照片→浮世绘)3.040.69↓77%
G_A / D_A0.54 / 0.260.73 / 0.03对抗平衡
G_B / D_B1.08 / 0.460.23 / 0.06对抗平衡

关键发现

  • 不对称数据集(B 域仅 562 张)下,cycle_B 反而更好 —— "去风格化"比"风格化"更易学
  • LSGAN 训练稳定,未出现模式坍塌
  • Identity loss 有效抑制不必要的颜色改变

4.4 推理脚本

编写了 infer_ukiyoe.py,支持单张图像推理:

bash
python infer_ukiyoe.py --input photo.jpg --output ukiyoe_result.png --epoch 40

五、改进方案

在分析原始架构不足后,设计了四个维度的改进,并修正了原方案中的多处代码 Bug。

5.1 改进点一:自注意力残差块 + U-Net 生成器

在 ResNet-9blocks 基础上引入:

  • Self-Attention:bottleneck 层获得全局感受野,gamma 初始化为 0,渐进式学习
  • SEA_ResnetBlock:局部卷积 + 全局注意力 + 恒等映射,三层并行
  • U-Net 跳跃连接:编码器各层特征直接传递给解码器,保留多尺度空间信息

5.2 改进点二:Auto-Encoder 判别器(EBGAN 风格)

用重建图像替代标量判别:

  • 编码器:256 → 8×8 特征图
  • 嵌入层:64 维压缩瓶颈
  • 解码器:8×8 → 256 重建图像(使用 Upsample+Conv 避免棋盘格)
  • 损失:MSE 重建误差(真实图能量低,生成图能量高)

5.3 改进点三:LPIPS 感知损失

用 LPIPS(预训练 AlexNet 特征空间距离)替代 L1 逐像素循环损失,更符合人类视觉感知。

5.4 改进点四:训练稳定性技巧

  • 标签平滑(Label Smoothing):Real ∈ [0.7, 1.2],Fake ∈ [0, 0.3]
  • 判别器输入加高斯噪声(std=0.05)
  • 判别器更新频率 G:D = 1:3

5.5 原方案 Bug 修正

严重程度问题修正
Criticalnorm_layer 通道不匹配每层独立指定通道数
CriticalSA 模块定义了但 forward 未调用整合进 bottleneck Sequential
HighWGAN-GP 与 AE 判别器不兼容明确选择 AE + MSE 路线
High梯度惩罚公式计算错误修正为 real*ε + fake*(1-ε)
Medium未定义的类引用移除或替换为正确实现

六、总结与展望

维度成果
框架理解深入掌握了统一训练骨架 + 动态装配的设计模式
复现验证maps/facades 数据集成功训练与测试
风格迁移浮世绘 40 epoch 训练完成,cycle loss 显著下降
方案设计自注意力 + AE 判别器 + LPIPS 完整方案 + Bug 修复
推理工具编写了单张图像推理脚本

后续优化方向

  • FID/KID 定量评估
  • 多尺度判别器
  • 频谱归一化
  • 数据增强(ColorJitter + RandomAffine)
  • 浮世绘数据扩充(博物馆数字档案)