简介基于GAN生成对抗网络的行人重识别毕业设计资源包面向深度学习、计算机视觉方向的高年级本科生和研究生适合正在开展相关课题或课程设计的读者。该课题聚焦跨摄像头下的行人检索任务利用生成对抗网络增强行人特征的判别性与域适应性是当前学术研究与工程应用中的热点。资源已通过导师审核作为高分毕业设计成果调试运行稳定可直接启动训练与测试流程。压缩包共48个文件主体为8个Python脚本辅以2份PDF实验报告、1份PPTX答辩演示、7个TXT配置记录、22张JPG结果图、3张PNG结构图并包含LICENSE、README等工程辅助文件整体仅18.49MB目录按代码、报告、演示和结果分层便于检索。已有409人学习下载内容覆盖数据预处理、GAN模型构建、行人重识别训练与评估全流程并配有实验报告和答辩PPT不仅适合作为毕业设计参考还能帮助初学者快速理解GAN在此任务中的实际落地方式。1. 用GAN做行人重识别先弄清楚这条路线能走多远白天从A栋大厅的监控里走过晚上又出现在B栋车库的摄像头里系统要从几百个陌生人的抓拍中认出这是同一个人——这就是行人重识别Person Re-identificationReID要回答的问题。标题里的“基于GAN深度学习生成对抗网络”并不是让GAN直接去做检索而是让它补偿ReID最难搞的短板同一个行人在不同摄像头下的外观差异太大而带标注的训练数据又太少。GAN本身就是生成对抗网络的缩写答辩时别把这两个词当成两个东西。这套方案在校园监控、商场客流、智慧安防项目里都有人用对做毕业设计或刚入门深度学习的开发者来说是性价比很高的切入点。如果你手里拿到这份源码目标是要跑出排得上号的检索结果、写出实验报告、答辩讲得清那你真正要搞清楚的是三件事数据怎么喂、标签怎么用、GAN怎么插进训练流程而不拖后腿。2. 数据集与评测口径rank-1 和 mAP 可信的前提2.1 公开数据集怎么选Market1501、DukeMTMC-reID 与 CUHK03 的取舍行人重识别最常见的基准数据集是 Market1501、DukeMTMC-reID 和 CUHK03。三个数据集的采集场景、标注方式和难度都不一样选哪个直接决定你的实验报告有没有说服力。做 GAN 增强方向的话首选 Market1501因为它的规模适中、划分文件是学术界默认口径跑一轮实验时间可控DukeMTMC-reID 相机数量更多、场景光照更杂能体现 GAN 对跨相机风格差异的补偿能力CUHK03 的检测框质量参差适合说明你的方法对检测误差鲁棒但训练难度明显更高。关于数据集大家口口相传的几个数字我给个常用口径你写报告时以官方划分文件为准别报错数据集训练身份数训练图像数query 数gallery 数特点Market1501751约 129363368159136 个摄像头校园场景划分最通用DukeMTMC-reID702约 165222228176618 个摄像头光照变化更大更难CUHK03767约 736814005328检测框/手工框两种标注难度高2.2 评测指标与计算口径rank-1 与 mAP 的常见误区评测一个 ReID 模型报告里最常出现两个指标rank-1 和 mAP。rank-1 的意思是对每个 query 行人系统从 gallery 里给出按相似度降序的检索列表排在第一位的那个结果恰好是同一个人。mAP 则看整个排序列表的质量——同一个人的所有正确结果是否尽可能排在前面。只看 rank-1 会掩盖“正确结果排第 2、第 3 位”的普通表现所以两个指标要一起报。这是检索类任务的基本共识也是答辩时老师必看的一组数。写完指标还要说清评测口径计算距离时query 和 gallery 来自同一个摄像头且身份相同的样本需要排除。否则模型只要学会“记住这个摄像头的背景”rank-1 就能虚高。这块属于“看着简单实际上特别容易翻车”的环节我见过不少人把同相机同身份样本算进 gallery最后 rank-1 刷到 95% 以上换数据集立刻掉回 50%。评测代码不复杂但口径错了整个实验就白做import numpy as np from scipy.spatial.distance import cdist # query_feats / gallery_feats 是 L2 归一化后的特征向量 dist cdist(query_feats, gallery_feats, metriccosine) # 按距离从小到大排序得到每个 query 对应的 gallery 下标序列 rank_idx np.argsort(dist, axis1) # 屏蔽规则排除 与 query 相同的摄像头编号 且 身份标签相同 的 gallery 样本 # 这是 Market1501 官方评测的默认口径少了这步指标会虚高 valid ~((same_cam_mask 1) (gallery_label query_label)) for i in range(len(rank_idx)): valid_rank rank_idx[i][valid[i]] # 计算第一个命中正确身份的排名位置再统计 rank-k2.3 训练集与验证集的切分原则ReID 数据集的标注形式是“身份 ID 摄像头编号 图像路径”训练和测试的身份集合是严格不相交的。这一点和 ImageNet 分类完全不同分类任务里测试类别在训练里见过ReID 必须保证测试行人从未出现在训练中否则就是“认识这个人”而不是“认出这个人”。做实验时你要检查自己的数据加载代码有没有把训练集的 ID 泄漏到测试集一个常见低级错误是数据划分时用了全局随机打乱导致同一个人既在 train 里又在 query 里。用 GAN 增强时还要注意生成图像的标签必须继承源图像的身份 ID不能凭空分配新 ID。生成样本只是同一个行人在新姿态、新光照下的外观变换身份标签不能变。如果生成器把两张不同身份的图像融合成一张这张图的标签就没人说得清喂进训练集后会让分类头学出错误边界。这是 GAN-ReID 方向最容易忽略的标签伪标定问题后面第 4 章会细讲。3. GAN 在 ReID 里的真实角色数据增强、特征对抗与损失设计3.1 三类典型做法图像风格迁移、姿态生成与特征级对抗GAN 在 ReID 里的角色从来不是“主力模型”而是陪练。最常见的三类做法难度和收益从低到高排列第一类是图像风格迁移。用 CycleGAN 或 StarGAN 把 A 摄像头的行人图像转成 B 摄像头的光照、纹理风格身份保持不变。这样做的好处是不需要跨摄像头的成对标注CycleGAN 天然支持非配对训练。实际项目里我会把 Market1501 的 6 个摄像头按“光照差异大”的原则分成两组做风格迁移后扩充训练集。这个做法实现简单训练稳定适合毕业设计做基线增强。第二类是姿态生成。用姿态关键点引导生成器把行人从正面视角转成侧面或背面。这类做法需要额外的姿态估计模型比如 OpenPose 或 AlphaPose成本高但能直接补足 ReID 最头疼的视角缺失问题。训练时容易踩坑姿态关键点预测错了生成出来的图像肢体扭曲反而污染训练集。我的经验是离线跑一批生成结果肉眼筛一遍再做数据混合别全自动灌进去。第三类是特征级对抗。不做图像层面的生成而是给骨干网络的特征加一个判别器判别器负责判断“这个特征来自哪个摄像头”。如果特征中包含了相机风格的偏置判别器就能轻松分辨出来反过来骨干网络会尽量去掉这些偏置信息让判别器分不清。这个做法不产生额外图像训练开销小但调参难度高特征层的分布不像图像那样直观出了问题很难排查。3.2 把 GAN 输出接进 ReID 训练两种接入方式对比接入方式决定了你的整个训练流程怎么组织。我用过两种方案各有利弊接入方式实现要点优点缺点离线生成 混合训练先用 GAN 生成一批增强图像保存到磁盘再和原图按比例混合成一个数据集训练稳定生成和 ReID 训练解耦出问题容易定位生成图像多样性固定无法根据 ReID 训练状态动态调整在线对抗训练生成器与 ReID 模型在同一训练循环中交替更新生成分布会随训练动态变化理论上更能适配困难样本训练不稳定显存占用翻倍调参难度大对毕业设计和大部分项目我强烈推荐离线方案。理由是在线方案把两个不稳定系统绑在一起生成器崩溃时 ReID 模型也会跟着掉点你会分不清是 GAN 训崩了还是 ReID 训练有问题。离线方案相当于给实验加了一道闸先把生成质量这个变量控制住再做对比。答辩时离线方案也更方便画流程图和数据管线老师听着不累。3.3 生成样本不能直接灌进训练集标签伪标定与采样比例直接把 GAN 生成的图像灌进训练集是新手最容易犯的错误而且刚开始看不出问题。生成图像和原图在分布上仍有差异如果混合比例过高ReID 模型会对生成图像的纹理过度拟合导致在真实测试集上掉点。我一般把生成样本的比例控制在 20%~40%具体看生成质量来调整。另外要注意标签伪标定风格迁移类方法只是变换了外观身份 ID 不变可以采用硬标签但如果是姿态生成或跨域生成生成图像的质量参差部分图像的判别性特征已经被破坏这时可以用标签平滑或给生成样本设置一个较低的权重让模型“参考但不盲信”。我在实验里常用的做法是给生成样本的 ID 分类损失乘一个 0.5 的系数三元组损失正常算这样既能利用生成样本的多样性又不会让它们喧宾夺主。4. 在 Python 里跑通最小 GAN-ReID 实验环境搭建、训练步骤与 3 个必调参数4.1 环境搭建先从 CPU 跑通流程再上 GPU拿到源码的第一步不是直接训练而是先把环境搭好、把测试流程跑通。官方代码库或毕设工程一般基于 PyTorch环境配置遵循固定顺序能省掉一半的“玄学报错”。我建议的安装顺序是先建 conda 虚拟环境再装 PyTorch最后装 scipy、tensorboard、tqdm 等辅助库。# 1. 创建独立环境避免和别的项目互相污染 conda create -n reid python3.8 # 2. 激活环境 conda activate reid # 3. 安装 PyTorch 与配套库 # 注意这里的 CUDA 版本要和你本机 nvidia-smi 显示的驱动版本匹配 conda install pytorch1.12.1 torchvision0.13.1 cudatoolkit11.3 -c pytorch # 4. 安装常用依赖 pip install scipy tqdm tensorboard pillow # 5. 验证 PyTorch 是否能调用 GPU python -c import torch; print(torch.cuda.is_available())这里的逻辑是先用 conda 锁住 Python 和 CUDA 的版本组合避免 pip 自动升级把环境搞乱。第 5 步如果输出 False先检查驱动再检查 cudatoolkit 版本不要急着重装。如果你的机器显存小于 6G先用 CPU 模式把数据加载和评测流程跑通确定代码没问题再换 GPU 训练否则每次改代码都要排队等显存效率太低。4.2 最小复现链路数据准备、训练、评估三阶段ReID 工程的目录结构通常包含 config、data、model、utils 几个模块。拿到源码后你需要先找到三个入口脚本数据划分脚本、训练脚本、评估脚本。一般会有一个 README 或 run.sh 说明执行顺序。我习惯让工程按下面这个流程工作# 阶段1数据准备 # 把 Market1501 原始数据按 train/query/gallery 划分好 # 得到 images.txt、train_path.txt、query_path.txt、gallery_path.txt 四个文件 python prepare_data.py --dataset market1501 --data_dir /path/to/Market1501 # 阶段2训练 ReID 模型此时不接入 GAN先建立基线 # 训练 60 个 epoch保存 best_model.pth python train.py --config configs/reid_base.yaml # 阶段3评估 # 加载训练好的模型输出 rank-1、mAP python test.py --config configs/reid_base.yaml --resume checkpoints/best_model.pth数据准备阶段最关键的是检查路径文件的行数是否匹配官方划分train_path 行数 12936query_path 行数 3368gallery_path 行数 15913。这三个数字对不上后面所有环节都会错。训练阶段先跑基线不要一上来就叠 GAN。先确认基线模型在 Market1501 上能达到公开论文的常见水平——现在主流方法在 90% 左右具体值随预训练和 trick 浮动——再开始加 GAN。4.3 三处必调参数生成器权重、混合比例与 BN 统计量GAN 接入 ReID 训练后有这三个参数值得反复调也是实验报告里最值得写的消融点。第一是生成样本在训练 batch 中的比例。我习惯用 0.3 起步生成质量高可以调到 0.4生成质量一般就降到 0.2。这个参数直接控制模型对生成分布的拟合程度。第二个是生成样本的 ID 损失权重前面说过从 0.5 起步如果发现 rank-1 不升反降优先调它。第三个是 BN 层的统计量设置这是 ReID 训练里公认的“细节决定成败”在行人重识别里模型最终只保留 backbone 的全局特征分类层会丢弃所以 backbone 的最后一个 stage 的 BN 需要把 momentum 调大比如 0.1并关闭 bias。这个 trick 能让特征分布更稳定rank-1 能涨 1~3 个点。# 最小 GAN-ReID 训练循环中的核心损失计算 import torch import torch.nn.functional as F # 假设 # backbone 输出特征 f形状 [batch_size, 2048] # classifier 输出 ID 分类 logits形状 [batch_size, num_ids] # 每个 batch 中前 num_gen 个样本是 GAN 生成的增强图像 def compute_loss(f, logits, labels, num_gen, lamda0.5): # 1. ID 分类损失所有样本都参与但生成样本权重降低 loss_id_all F.cross_entropy(logits, labels) loss_id_gen F.cross_entropy(logits[:num_gen], labels[:num_gen]) loss_id (1 - lamda) * loss_id_all lamda * loss_id_gen # 2. 三元组损失主要约束真实样本之间的相对距离 # 这里用 batch-hard 策略采样难正例和难负例 loss_triplet triplet_loss(f[num_gen:], labels[num_gen:], margin0.5) # 3. 总损失backward 后统一更新 backbone 和 classifier return loss_id loss_triplet这段代码的逻辑是生成样本参与了 ID 分类损失但对难样本三元组损失不贡献。原因是生成样本的特征分布和真实样本有偏移让它们参与三元组计算会拉偏特征空间的距离度量。如果你做完实验发现 rank-1 不升反降优先检查这个设置——把生成样本的全部分类权重去掉只保留数据多样性有时反而效果更好。这边的损失权重 0.5 只是一个起点你的实验报告里应该做成一个参数扫描表0.0、0.3、0.5、0.7 各跑一遍报告会非常扎实。5. 行人重识别避坑清单5 个必经的坑与排查路径5.1 训练损失下降但 rank-1 纹丝不动BN 统计量在作怪现象训练集损失一路下降收敛也正常但测试集 rank-1 卡在 40% 左右上不去。原因ReID 模型在训练时用 batch 内的 BN 统计量推理时用全局统计量。如果训练时 batch size 太小BN 的均值方差估计不准模型学习到的特征分布和推理时不一致。另一个常见原因是骨干网络最后一层 BN 没有特殊处理导致特征在推理时分布漂移。解决把骨干网络最后一个 stage 的 BN momentum 设为 0.1并设置 affine 参数中的 bias 为 Falsebatch size 尽量不小于 16如果显存不够就把输入分辨率从 256x128 降到 128x64而不是强行减小 batch size。这个改动通常能带来 2~4 个点的提升属于成本最低的涨点手段。5.2 GAN 生成的图像全是黑白噪点或色块现象生成器输出的图像看起来像随机噪声完全看不出行人轮廓训练损失里生成器 loss 一直在震荡。原因多数情况下是生成器的输出层没有匹配图像数据的归一化范围。ReID 输入图像经过归一化后像素范围在 [-1, 1]而生成器输出层如果用了 sigmoid范围 [0, 1]或者没有加 tanh就会导致图像失真。另一个原因是判别器学习率过高把生成器压得毫无还手之力。解决检查生成器最后一层是否为 tanh 激活把判别器换成带谱归一化的结构学习率设置为生成器的一半。同时把 GAN 损失从普通 BCE 换成 LSGAN 或 WGAN-GP训练稳定性会好很多。顺带说一个血泪经验生成图像直接可视化看效果不要只觉得 loss 数字好看就行。5.3 显存不够但代码能跑batch size 与分辨率的取舍现象程序启动时报 CUDA out of memory但代码逻辑本身没问题。原因ReID 计算的是整图的全局特征图像分辨率越高、batch size 越大显存占用越高。如果同时跑生成器和 ReID 模型显存需求直接翻倍。解决优先降 batch size保证每个 batch 内身份数量足够比如 8 个身份每个身份 4 张图再降输入分辨率从 256x128 降到 224x112 或 128x64。要注意的是离线生成 GAN 图像可以在廉价机器上批量跑完存成图片后再开始 ReID 训练这样能绕开显存瓶颈。在线训练的显存代价不小对设备不友好的情况建议直接放弃。5.4 跨域测试效果暴跌数据集的风格偏置现象在 Market1501 上 rank-1 有 80% 多直接换到 DukeMTMC-reID 上测试掉到 20% 以下。原因ReID 对数据集的风格偏置非常敏感。训练集里的摄像头数量、光照条件、行人姿态分布都被模型学进了特征里换一个数据分布就失效。很多论文为了掩盖这个问题只做同域内的随机划分这在实际项目里没有太大参考价值。解决训练阶段引入风格迁移 GAN 做跨数据集增强把 Market1501 的图像转成 Duke 风格评估阶段一定要留出跨域测试集不能只在同域内自嗨。如果你的硬件资源有限至少要在实验报告里诚实说明同域评测的局限答辩老师更看重你是否知道这个问题存在。5.5 答辩被问“GAN 提升有限怎么解释”先做消融现象加了 GAN 之后rank-1 只涨了 0.3 个点实验报告不知道怎么圆。原因这根本不是 bug而是常态。基线模型本身已经学得不错时GAN 增强带来的增量必然有限。真正的工作量不在“跑出涨点”而在“分析涨在哪”是困难样本上的 rank-1 涨了还是 mAP 涨了在哪些摄像头对之间涨得最多解决准备一张消融表列四行baseline、baseline 随机裁剪翻转、baseline GAN 增强、baseline GAN 增强 标签平滑。再按 query 难度把样本分成简单/中等/困难三组分别报 rank-1。这组数据比在答辩台上解释“GAN 就是有用”有说服力得多。诚实地说我见过不少答辩现场老师问的第一个问题就是“你的提升是不是数据增强带来的换 RandomErasing 是不是也一样”没有这张消融表这个问题基本答不上来。6. 进阶验证从训练曲线到跨域泛化的三个自检动作6.1 训练曲线之外看生成图质量和特征分布两个“黑匣子”训练曲线只能说明损失在降不能说明 ReID 特征质量在涨。我的习惯是每 5 个 epoch 保存一批生成图像肉眼检查清晰度、姿态自然度和身份一致性。特征分布方面随机抽 20 个身份的特征做 TSNE 可视化如果同一个身份的特征聚成一团、不同身份之间分得开说明特征判别性不错。如果 TSNE 图上出现明显的摄像头分簇说明特征还残留相机风格信息风格迁移模块没过关。6.2 跨域验证同域评测通过不代表能用把模型在 Market1501 上训练好直接拿去 DukeMTMC-reID 的 query/gallery 上测一遍这就是跨域评测。如果 rank-1 掉得很惨你需要引入域适应或更强的风格增强。实际项目部署前这一步是绕不开的。我认识的一线工程师在项目验收前都会专门准备一份真实场景的采集数据当评测集用训练时的同款评测脚本打分避免实验室指标和现场表现差出一个量级。这个自检动作虽然费时间却代表你的实验报告有真正的工程价值。6.3 给答辩的最后一道准备一张消融对比表与两个必答追问消融表不要做得太复杂我建议按下面这个模板组织具体数字用你自己的实验结果填写配置rank-1mAP说明baseline88.371.2ResNet50 基线baseline 常规增强89.172.5随机翻转、裁剪baseline GAN 风格迁移90.274.0生成样本比例 0.3baseline GAN 标签平滑90.674.8生成样本权重 0.5答辩时会有两个必答追问你要准备好。第一个是“为什么用 GAN 而不是直接加更强的数据增强”答案核心是 GAN 能生成训练集中不存在的分布组合比如把 A 摄像头的身份放到 B 摄像头的光照下这是传统数据增强做不到的。第二个是“GAN 训练不稳定怎么控制”你可以回答谱归一化、梯度惩罚、判别器学习率降为生成器的一半、离线生成切断训练耦合。最后说一个我自己的教训读研时第一次跑 GAN-ReID狠狠堆了三个生成器成果展示时发现收益还不如多调两天 BN 参数。后来我想明白了GAN 在 ReID 里永远是放大器不是救世主你的基线和评测口径不稳GAN 再强也救不回来。先跑通流程再谈生成质量最后追求涨点这个顺序不要颠倒。希望帮到你。本文还有配套的精品资源点击获取