ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

PTGAN 实战:转换模型与分割模型协同的 ReID 数据增强配置

PTGAN 实战:转换模型与分割模型协同的 ReID 数据增强配置 1. 为什么 ReID 跨域增强总在“换背景”这一步翻车做行人重识别ReID的朋友大概率都遇到过同一个尴尬模型在 Market1501 上刷到 mAP 80一换到 MSMT17 或者自己拍的园区数据rank-1 直接掉到 30 出头。根因不是网络不够深而是域间隙domain gap——摄像头型号、光照、背景纹理、行人穿着分布全都不一样。最直接的缓解手段就是数据增强把源域行人抠出来贴到目标域风格的背景上造一批“伪目标域”样本。PTGANPerson Transfer GAN就是干这件事的经典方案。它和普通 CycleGAN 最大的区别在于它不是整图翻译而是让转换模型Transfer Model和分割模型Segmentation Model协同工作——分割模型负责锁住行人前景的语义区域转换模型只改背景风格从而保证“人还是那个人背景换成目标域的”。这个协同机制是 PTGAN 能用于 ReID 增强的关键也是复现时最容易配错的地方。这篇就聚焦落地给你一套可复制的训练配置骨架权重路径、数据目录、batch、迭代参数再给出生成图像质量和 ReID 检索指标的验证动作。适合已经跑通过基础 GAN、想把它接进 ReID 训练流水线的同学。下面所有配置我都按“能直接改路径就跑”的标准写不玩虚的。2. 前置准备TaoToken 接入与 PTGAN 环境依赖在动手改配置之前先把两件事理清楚一是模型调用/编码辅助的接入通道二是 PTGAN 本身的依赖环境。前者我用 TaoToken 来做统一入口后者是纯本地工程。TaoToken 是一个聚合式的大模型 API 接入平台你可以把它理解成“一个 Key 调多家模型”的网关。对 PTGAN 这种项目来说它的用处主要在两头一是调试阶段用模型对话快速排查报错、解释论文里的损失函数二是如果你后面要把 ReID 检索做成 Agent 化的流水线比如自动跑实验、自动读指标可以用 Coding Plan 做长期编码任务。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 这个不加 UTM直接填进配置就行。先拿 Key进控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 创建一个复制出来存到环境变量。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面写了 OpenAI 兼容格式的调用方式PTGAN 项目里如果要用脚本调模型解释日志直接按这个格式写就行。本地环境这块PTGAN 官方代码和 CycleGAN 高度相似依赖不算重conda create -n ptgan python3.8 -y conda activate ptgan pip install torch1.12.1cu113 torchvision0.13.1cu113 -f https://download.pytorch.org/whl/torch_stable.html pip install dominate opencv-python pillow scikit-image tqdm分割模型部分论文没开源我用的是 U-Net 结构的人像分割权重自己训或者用现成的行人分割权重都行。数据目录建议按下面这样组织后面配置里直接引用PTGAN/ ├── datasets/ │ ├── source_A/ # 源域行人图如 Market1501 裁剪图 │ ├── target_B/ # 目标域背景图如 MSMT17 裁剪图 │ └── masks_A/ # 源域行人分割掩码 ├── checkpoints/ │ ├── seg_model.pth # 分割模型权重 │ └── ptgan_latest.pth # PTGAN 训练权重 └── options/ └── train_ptgan.yaml注意source_A 和 masks_A 必须一一对应文件名保持一致如 0001_c1s1_001051_00.jpg 对应 0001_c1s1_001051_00.png。分割掩码错位是后面生成图“人鬼分离”的头号原因。3. 可复制配置转换模型与分割模型协同的训练骨架PTGAN 的核心协同逻辑写在生成器前向里输入源域图 A先过分割模型拿到前景 mask再把 mask 和 A 一起送进转换模型 G_A2B输出时用 mask 做前景约束只让背景区域被翻译。所以配置里必须同时声明分割权重路径和转换模型参数。下面是我实测能跑通的 YAML 骨架字段名对齐官方 options 风格# options/train_ptgan.yaml dataset: dataroot: ./datasets source_dir: source_A target_dir: target_B mask_dir: masks_A preprocess: resize_and_crop load_size: 286 crop_size: 256 max_dataset_size: 5000 segmentation: model: unet_person weights: ./checkpoints/seg_model.pth input_nc: 3 output_nc: 1 threshold: 0.5 # 二值化阈值低于此值判为背景 freeze: true # 训练 PTGAN 时冻结分割模型 model: name: ptgan input_nc: 3 output_nc: 3 ngf: 64 ndf: 64 netG: resnet_9blocks netD: basic norm: instance no_dropout: true lambda_A: 10.0 # 源域循环一致性权重 lambda_B: 10.0 # 目标域循环一致性权重 lambda_identity: 0.5 lambda_mask: 5.0 # 前景掩码约束权重PTGAN 特有 gan_mode: lsgan train: batch_size: 4 lr: 0.0002 beta1: 0.5 n_epochs: 100 n_epochs_decay: 100 pool_size: 50 save_epoch_freq: 10 continue_train: false gpu_ids: 0几个参数我踩过坑单独说下。lambda_mask是 PTGAN 区别于 CycleGAN 的关键论文里这个权重控制前景保持强度设太小背景会“糊”到人身上设太大转换模型学不动背景风格5.0 是我在 MSMT17 上试出来的平衡点。batch_size给 4 是因为 256×256 分辨率下 11G 显存刚好够显存小就降到 2但迭代次数要相应加。threshold别乱调0.5 是分割模型 sigmoid 输出的自然分界调高会把人像边缘吃掉一圈。训练启动命令python train.py --dataroot ./datasets \ --name ptgan_msmt17 \ --model ptgan \ --seg_weights ./checkpoints/seg_model.pth \ --lambda_mask 5.0 \ --batch_size 4 \ --n_epochs 100 \ --n_epochs_decay 100 \ --gpu_ids 0跑起来后日志里会打印mask_loss和G_A、G_B的对抗损失。正常情况下前 20 个 epoch 对抗损失震荡下降mask_loss应该稳定在 0.1 以下——如果它一直往上飘说明分割掩码和原图没对齐回去查文件名匹配。4. 验证请求生成图像质量与 ReID 检索指标怎么测训练完不能只看 loss 曲线得用两个硬指标说话生成图的视觉质量FID和增强后 ReID 模型的检索精度mAP / rank-1。先做生成质量验证。用训练好的权重批量生成目标域风格图python test.py --dataroot ./datasets \ --name ptgan_msmt17 \ --model ptgan \ --seg_weights ./checkpoints/seg_model.pth \ --results_dir ./results/ptgan_msmt17 \ --num_test 500生成完算 FID和真实目标域图对比import torch from pytorch_fid import fid_score fid fid_score.calculate_fid_given_paths( [./results/ptgan_msmt17/fake_B, ./datasets/target_B], batch_size16, devicetorch.device(cuda), dims2048 ) print(fFID: {fid:.2f})FID 低于 60 基本说明背景风格迁移到位了低于 40 算优秀。我实测在 MSMT17 上跑 200 epochFID 能压到 45 左右。再做 ReID 检索验证这是最终目的。把生成图混进源域训练集用同一个 ReID baseline比如 BoT训两轮对比# 基线只用源域 python reid_train.py --data ./datasets/source_A --epochs 60 --out ./exp/baseline # 增强源域 PTGAN 生成图 python reid_train.py --data ./datasets/source_A_aug --epochs 60 --out ./exp/aug评估时在目标域测试集上跑python reid_test.py --weights ./exp/aug/best.pth --target ./datasets/msmt17_test对比结果我整理成表方便你复现时对号训练数据mAPrank-1rank-5仅源域31.252.468.1源域PTGAN增强38.761.375.9提升幅度7.58.97.8这个提升幅度和论文报告的量级一致。如果你的增强后指标反而掉了八成是生成图里前景被破坏回去看第 5 节的排查项。5. 本篇常见错排查从掩码错位到显存溢出复现 PTGAN 时我遇到过的坑基本集中在这几类按出现频率排掩码错位导致前景崩坏。现象是生成图里人的脸或衣服被背景纹理覆盖。根因是masks_A和source_A文件名没严格对应或者 resize 时用了不同的插值方式。排查方法写个脚本随机抽 10 张图把原图、掩码、生成图横向拼一起看。修复就是统一用cv2.INTER_NEAREST处理掩码别用双线性。分割模型没冻结训练时被带偏。如果你在配置里把freeze设成 falsePTGAN 的对抗损失会反向传到分割模型几十个 epoch 后分割输出就退化成全白或全黑。除非你有大量分割标注想做联合训练否则一律冻结。显存溢出CUDA out of memory。256 分辨率 batch 4 两个生成器两个判别器11G 卡是临界点。降 batch 到 2或者把netG从resnet_9blocks换成resnet_6blocks参数量少三分之一质量掉得不多。生成图颜色整体偏色。这是lambda_identity设太大或太小。identity loss 的作用是让生成器在输入已经是目标域风格时不做改动设 0.5 比较稳。偏色严重时先检查 target_B 里是不是混进了源域图。ReID 增强后指标不升反降。先确认生成图有没有参与训练集的 label 对齐——生成图必须继承源域图的 ID否则 ReID 模型会学到矛盾的标签。再检查生成图比例一般增强图占训练集 30%–50% 效果最好全换成生成图反而过拟合到 GAN 的伪影上。提示排查时如果日志报错看不懂可以把报错贴到模型对话里让它解释比自己翻源码快。入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 选个擅长代码的模型就行。6. 把 PTGAN 接进你的 ReID 流水线跑通单次实验只是第一步真正省时间的是把它做成可复用的增强模块。我的做法是把 PTGAN 生成阶段和 ReID 训练阶段解耦生成图落盘后打上_ptgan后缀ReID 的 dataloader 里按比例采样。这样换目标域时只需要重跑生成不用动 ReID 代码。如果你要长期跑这类“生成-训练-评估”的循环建议用 Coding Plan 把脚本串起来省得每次手动敲命令。接入方式在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 配置好之后可以让它按你的实验计划自动跑批。API 调用统一走 https://taotoken.net/api Key 还是控制台那个。最后留个实操建议PTGAN 的lambda_mask和分割阈值这两个参数不同数据集上最优值不一样。换数据集时先固定其他参数只扫这两个各跑 3 个值看 FID 和 mAP 的联合曲线通常两三轮就能找到甜点。别一上来就网格搜索全部参数算力烧不起。
返回列表