复现_基于条件GAN的陶瓷纹样生成
构建陶瓷数据
截取176对数据,正面图 + 纹样展开图,构建pix2pix所需要的数据集 合并 正面图 纹样图
理论支撑
-
论文:Image-to-Image Translation with Conditional Adversarial Networks
-
github地址:https://github.com/phillipi/pix2pix
-
优化项:增加感知损失
-
论文:Perceptual Losses for Real-Time Style Transfer and Super-Resolution Johnson et al., 2016(ECCV)
-
优化项:
- 原Pix2Pix:只有单尺度PatchGAN,只能看局部patch,容易纹理断裂,结构不连续
- 多尺度Pix2Pix:同时看全局结构,中尺度纹理,局部细节
- 相当于 从多个分辨率同时监督生成器
-
论文:High-Resolution Image Synthesis and Semantic Manipulation with Conditional GANs
训练数据
- 安装基础依赖,关闭wandb
pip install dominate pillow
删掉 util/visualizer.py 中 import wandb
- 运行训练命令
训练数据:测试数据=8:2 (140:36)
--dataroot datasets/ceramic # 数据集路径
--name ceramic_pix2pix # 实验名字,用来保存模型 保存日志 区分实验 输出位置
--model pix2pix # 选择模型,条件GAN,成对图像翻译
--direction AtoB # 输入->输出方向
--netG unet_128 # 生成器结构encoder+decoder结构,保留空间信息 很重要
--batch_size 1 # 每次喂一张图
--load_size 256 # 输入图缩放到256,原始图片会变成256*256
--crop_size 256 # 裁剪尺寸
--n_epochs
-lr
--lambda_L1
--n_epochs 50 # 让训练更平滑,前期快速学习,后期慢慢收敛
--n_epochs_decay 150 # 让训练更平滑,前期快速学习,后期慢慢收敛
-lr 0.0001 # 调整学习率,更稳定
--n_epochs 150 # 更稳定
--n_epochs_decay 50 # 更稳定
训练轮数epochs = n_epochs + n_epochs_decay,前n_epochs轮学习率不变(快速学结构,GAN稳定对抗),后n_epochs_decay轮学习率逐渐衰减变成0(细化纹理,稳定收敛,减少震荡)
--lambda_L1 50 # 调整lambda_L1的权重,默认100,值大更像真实图 可能模糊,值小更锐利 可能不稳定
A:Baseline(你现在已经在跑)
python train.py --dataroot datasets/ceramic --name pix2pix_A_baseline --model pix2pix --direction AtoB --netG unet_128 --batch_size 1 --load_size 256 --crop_size 256 --lr 0.0002 --n_epochs 100 --n_epochs_decay 100 --lambda_L1 100
B:学习率调度优化(重点实验)
python train.py --dataroot datasets/ceramic --name pix2pix_B_lr_decay --model pix2pix --direction AtoB --netG unet_128 --batch_size 1 --load_size 256 --crop_size 256 --lr 0.0001 --n_epochs 50 --n_epochs_decay 150 --lambda_L1 100
C:Loss调整实验(纹理更锐利)
python train.py --dataroot datasets/ceramic --name pix2pix_C_l1_variant --model pix2pix --direction AtoB --netG unet_128 --batch_size 1 --load_size 256 --crop_size 256 --lr 0.0002 --n_epochs 100 --n_epochs_decay 100 --lambda_L1 50
实验A:基线(λ=0)
python train.py --dataroot datasets/ceramic --name ceramic_pix2pix_base --model pix2pix --direction AtoB --netG unet_128 --batch_size 1 --load_size 256 --crop_size 256 --n_epochs 100 --n_epochs_decay 100
实验B:增加感知损失 (λ=5)
python train.py --dataroot datasets/ceramic --name ceramic_pix2pix_p5 --model pix2pix --direction AtoB --netG unet_128 --batch_size 1 --load_size 256 --crop_size 256 --lambda_perceptual 5 --n_epochs 100 --n_epochs_decay 100
实验C:增加感知损失 (λ=10)
python train.py --dataroot datasets/ceramic --name ceramic_pix2pix_p10 --model pix2pix --direction AtoB --netG unet_128 --batch_size 1 --load_size 256 --crop_size 256 --lambda_perceptual 10 --n_epochs 100 --n_epochs_decay 100
评估阶段的执行语句:
python eval_stage.py --dataroot datasets/ceramic --name pix2pix_A_baseline --model pix2pix --direction AtoB --dataset_mode aligned --phase val --no_dropout
测试阶段的执行语句:
python test_stage.py --dataroot datasets/ceramic --name pix2pix_A_baseline --model pix2pix --direction AtoB --dataset_mode aligned --epoch 55 --phase test --no_dropout
推理阶段的执行语句:
python inference_stage.py --dataroot datasets/ceramic --name pix2pix_A_baseline --model pix2pix --direction AtoB --dataset_mode aligned --epoch 55 --phase test --no_dropout

| 参数 | --n_epochs(训练轮数) | --lr | --lambda_L1 | --n_epochs_decay | --lambda_perceptual |
|---|---|---|---|---|---|
| 本质作用 | 控制训练时间长度,学习学多久 | 控制学习速度,学得快不快/稳不稳 | 重建约束强度,输出像不像真实图 | 什么时候让模型慢慢收敛,后n_epochs_decay轮学习率逐步减至0 | 控制 感知约束强度 |
| 是什么 | 模型 完整看数据多少遍 | 每次更新参数迈多大步 | 控制 生成图像要不要像真实图 | 控制什么时候开始收缩步子,前期:大步走(学习结构),后期:小步走(优化细节) | 控制Perceptual Loss在总损失中的权重 |
| 影响机制 | epoch越高,学得更充分;epoch越低,学得不够 | 值大,学得快,但不稳定;值小,学得慢,但更精细; | Pix2Pix:Loss=GAN_loss + λ * L1_loss,GAN_loss:让图像看起来像真的,L1_loss:让图像和真实答案一致; | / | 如果lambda_perceptual太小,几乎没作用,等于没加;如果lambda_perceptual太大,模型只学VGG特征,结构可能崩 |
| 不同值效果 | 小(50):欠拟合,图像模糊,结构不完整,训练快,纹样还没学会;中(100-200):学得稳定,结构+纹样都能学到,Pix2Pix标准区间;太大(300+):过拟合,记忆训练集纹样,泛化变差,输出训练图复刻 | 大(0.0004):震荡,可能不收敛,前期收敛快,图像忽好忽坏;默认(0.0002):最稳定,Pix2Pix推荐;小(0.0001):稳定,细节更好,收敛慢,图更干净但是训练,慢; | 大(100-200):默认,更接近真实纹样,结构稳定,可能略模糊;中(50-80):更自由生成,纹理更锐利,可能不完全对齐真是图;小(10-30):失去约束,结构漂移,GAN主导,看起来像,但不对 | delay早(50):更早进入精细优化,可能更稳定,但学习不够充分,图像更干净,但可能欠拟合;dealy默认(100+100):Pix2Pix标准,平衡学习+收敛;decay晚(150+50):学习时间更长,更容易过拟合,纹理更记忆化,很像训练集,但泛化弱 | 值小,结果偏模糊;值中等(λ=5,最稳定、最常用平衡点,不会压过L1,不会破坏GAN训练,视觉效果通常最好),效果纹理清晰;值大,效果过拟合纹理((λ=10,测试强感知约束是否过拟合,可以展示纹理增强或细节过锐/失真风险); |
| 实验对比 | 参数设置 |
|---|---|
| A | --lr 0.0002 --n_epochs 100 --n_epochs_decay 100 --lambda_L1 100 |
| B | --lr 0.0001 --n_epochs 50 --n_epochs_decay 150 --lambda_L1 100 |
| C | --lr 0.0002 --n_epochs 100 --n_epochs_decay 100 --lambda_L1 50 |
训练结果分析
名词解释
- epoch
- 表示训练轮数,即完整看一遍数据集
- 案例:1个epoch 表示 模型把176对全部看一遍+学习一次;200个epoch 表示 看了200遍整个数据集
- G_GAN
- 表示生成器对抗损失
- 作用:判断 生成图像 骗不骗得过 判别器
- 效果:越小/合适越好(不是越小越好);值太高,判别器觉得假;值太低,生成器骗过了;
- G_L1
- 表示像素级误差,是Pix2Pix最核心损失,即 生成的纹样和真实纹样差多少
- 效果:G_L1越低 --> 纹样越接近真实展开图
- D_real
- 判别器看真图
- 判别器判断 真实图片 的结果
- 效果:理想输出真,值通常在0~1波动
- D_fake
- 判别器看假图
- 作用:判别器判断 生成图 的真假
- 效果:生成器越强 --> D_fake越接近真
一场博弈
- 生成器G:我要造假图
- 判别器D:我要识别真假
| 参数 | 角色 |
|---|---|
| G_GAN | 生成器 骗 判别器 的能力 |
| G_L1 | 生成图和真图的差距 |
| D_real | D识别真图 |
| D_fake | D识别假图 |
- 原理:在训练过程中,生成器根据输入的陶瓷正面图生成纹样展开图;判别器不断判断生成结果与真实纹样图的差异。两者通过对抗博弈共同优化,使生成器输出的纹样展开图在内容和视觉效果上越来越接近真实纹样图。
第一轮epoch0~200结果分析
- G_L1下降:
- epoch 9 → G_L1: 27
- epoch 50 → G_L1: 22
- epoch 84 → G_L1: 9
- epoch 100 → G_L1: 3.8
- epoch 200 → G_L1: 2.1
- 图像结构越来越准确
- G_GAN波动:
- 0.7 ~ 2.7 波动
- 说明:判别器在工作;生成器在对抗学习;
- GAN在正常对抗
- D_real / D_fake稳定
- D_real ≈ 0.3 ~ 0.8
- D_fake ≈ 0.1~0.8
- 判别器没有崩
- 数据分析
- Stage1:epoch 1-30:模糊+结构错误
- Stage2:epoch 30-100:开始出现纹样结构,但边缘粗糙
- Stage3:epoch 100-200:结构基本正确,细节仍有噪声
- Stage4:epoch 200+:论文可用图
- 现在已经看到不错的效果:因为这个任务从 正面陶瓷图 到 展开纹样图,本质是 强结构映射 + 中等复杂纹理生成,Pix2Pix是刚好匹配这个任务的模型
说明
从https://huggingface.co/上下载预训练权重参数
- HuggingFace模型:站在别人训练好的经验上继续训练
- 预训练权重 = 别人已经训练好的模型参数(经验)
- 微调是 加载别人训练好的权重,然后继续训练
Pix2Pix
- 从零学习
为什么Pix2Pix不需要HF模型?
- Pix2Pix本质是:专门为成对图像翻译设计的小模型
- 特点:U-Net结构;GAN+L1loss;不依赖大规模语义知识;可以直接从数据中学习;
本文来自博客园,作者:jsqup,转载请注明原文链接:https://www.cnblogs.com/jsqup/p/20654939

浙公网安备 33010602011771号