3、人脸数据集详解:主流公开数据集与数据工程
做人脸比对模型,数据就是一切。模型再牛,喂进去的数据不行,结果就是白搭。我见过太多团队花几个月调网络结构,最后发现是训练集里混了大量重复或错误标签的图片——说白了,模型根本没学到人脸长啥样,光在那背答案了。
这一章,咱们就聊聊数据。我会把主流数据集的特点、数据清洗的坑、以及我常用的增强手段,一次性说清楚。
3.1 主流公开数据集:你得知道它们长什么样
先看几个最常用的。每个数据集都有自己的脾气,选哪个取决于你的任务场景。
| 数据集 | 身份数 | 图片数 | 特点 | 我的评价 |
|---|---|---|---|---|
| LFW | 5,749 | 13,233 | 自然场景,非受限 | 评测基准,太小不适合训练 |
| MegaFace | 690,000+ | 100万+ | 含干扰集,挑战大 | 评测用,训练需谨慎 |
| MS-Celeb-1M | 100,000 | 800万+ | 大规模,噪声多 | 经典但必须清洗 |
| VGGFace2 | 9,131 | 330万+ | 姿态、年龄、光照丰富 | 质量高,我常用 |
LFW 是绕不开的评测集。它只有一万多张图,但每张都是真实场景。我习惯用它做最终验证,而不是训练。你想想看,模型在 LFW 上能跑到 99.5% 以上,才算及格。
MegaFace 的挑战在于它包含 100 万干扰集。评测时,模型要从海量干扰项里找出正确的人。这个场景很贴近现实——比如安防系统在千万级底库里找人。但我不建议直接用 MegaFace 训练,它的标签噪声不小。
MS-Celeb-1M 是当年的明星数据集。800 万张图,10 万个名人。但问题也很明显:很多图片是新闻截图,同一个人的图片可能来自同一篇文章,背景、光线几乎一样。模型学到的不是人脸特征,而是背景记忆。嗯,这里要注意,用这个数据集必须做清洗。
VGGFace2 是我个人比较偏爱的。它只有 9,131 个身份,但每个身份有 300-500 张图,覆盖了各种姿态、年龄和光照。数据质量高,噪声少。我在很多项目里都用它做预训练,效果很稳。
我的建议: 如果你资源有限,直接用 VGGFace2 做预训练,再用 MS-Celeb-1M 清洗后的子集做微调。这个组合在大多数场景下都够用。
3.2 数据清洗与去重策略:别让模型学歪了
数据清洗,说白了就是给数据「排雷」。我接手过一个项目,模型在验证集上准确率很高,但一上线就崩。后来发现,训练集里同一个人的图片几乎都来自同一段视频,模型学的是背景纹理,不是人脸。
清洗的核心就两件事:去重 和 纠错。
3.2.1 去重:消除「记忆效应」
去重分两个层面:
- 图片级去重: 同一张图片出现在多个身份文件夹里。这种情况在 MS-Celeb-1M 里很常见。用 MD5 或感知哈希(pHash)就能搞定。
- 身份级去重: 同一个人的图片被标成不同身份。这需要聚类算法辅助。我常用的做法是:先用预训练模型提取特征,然后做 DBSCAN 聚类,把距离近的簇合并。
小技巧: 去重时别只看像素相似度。两张图可能像素完全不同,但人脸是同一个。用 FaceNet 或 ArcFace 提取的特征做相似度计算,阈值设 0.7 左右,效果不错。
3.2.2 纠错:清理「脏标签」
标签错误是家常便饭。我见过最离谱的,是把奥巴马的照片标成了特朗普。纠错方法很简单:
- 用清洗过的子集训练一个初始模型。
- 用这个模型对全量数据做预测。
- 把预测置信度低于 0.8 的样本挑出来,人工审核。
这个过程迭代 2-3 轮,基本能清理掉 90% 以上的错误标签。
注意: 清洗不是越狠越好。有些数据集里,同一个人的图片只有 2-3 张,去重太激进会把有效样本也删掉。我一般会保留每个身份至少 10 张图,低于这个数的直接丢弃。
3.3 数据增强技术:让模型见多识广
数据增强,就是给模型「加餐」。你想想看,模型只见过正面照,突然来一张侧脸,它肯定懵。增强的目的就是模拟真实世界的多样性。
3.3.1 随机裁剪:模拟局部遮挡
随机裁剪不是随便切。我习惯的做法是:
- 先检测人脸,得到 bounding box。
- 在 bbox 周围随机偏移 10%-20%,然后裁剪。
- 缩放到固定尺寸(比如 112x112)。
这样做的好处是,模型能学到「人脸不一定在正中间」这个事实。我在安防项目里用过这个技巧,模型对遮挡和偏转的鲁棒性提升很明显。
3.3.2 颜色抖动:对抗光照变化
颜色抖动,说白了就是随机调整亮度、对比度、饱和度和色相。代码很简单:
import torchvision.transforms as transforms
color_jitter = transforms.ColorJitter(
brightness=0.3,
contrast=0.3,
saturation=0.3,
hue=0.1
)
参数别设太大。亮度抖动超过 0.5,人脸就变成「鬼片」了。我一般控制在 0.2-0.3 之间。
3.3.3 MixUp:让模型学会「模糊边界」
MixUp 是我最近特别喜欢用的技巧。它不是简单的图片混合,而是把两张人脸按比例叠加,标签也按同样比例混合。
def mixup_data(x, y, alpha=0.2):
lam = np.random.beta(alpha, alpha)
batch_size = x.size()[0]
index = torch.randperm(batch_size)
mixed_x = lam * x + (1 - lam) * x[index]
mixed_y = lam * y + (1 - lam) * y[index]
return mixed_x, mixed_y
为什么有效?因为 MixUp 强迫模型在「两张脸的中间状态」也能做出合理判断。这相当于给决策边界加了平滑约束,模型泛化能力会更强。
我的经验: MixUp 的 alpha 参数很关键。alpha=0.2 时,混合比例接近 0 或 1 的概率大,模型学到的还是「纯」样本。alpha=1.0 时,混合比例均匀分布,模型会看到更多「模糊」样本。我一般从 0.2 开始试,看验证集效果再调。
3.4 知识结构图:数据工程的完整链路
下面这张图,是我做数据工程时脑子里始终绷着的一根弦。从原始数据到训练集,每一步都不能省。
这条链路,我每次做新项目都会走一遍。别嫌麻烦,数据工程花的时间,会在模型训练阶段加倍还给你。
最后说一句: 数据增强不是越多越好。我见过有人把 10 种增强全堆上,结果模型训练了 3 天还没收敛。先选 2-3 种最有效的,等模型稳定了再慢慢加。这个道理,跟做菜放调料一样——盐放多了,菜就毁了。