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 纠错:清理「脏标签」

标签错误是家常便饭。我见过最离谱的,是把奥巴马的照片标成了特朗普。纠错方法很简单:

  1. 用清洗过的子集训练一个初始模型。
  2. 用这个模型对全量数据做预测。
  3. 把预测置信度低于 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 知识结构图:数据工程的完整链路

下面这张图,是我做数据工程时脑子里始终绷着的一根弦。从原始数据到训练集,每一步都不能省。

人脸数据工程链路 原始数据集 数据清洗与去重 数据增强 随机裁剪 颜色抖动 MixUp 混合 高质量训练集 核心原则 清洗去重 → 增强多样性 → 混合泛化

这条链路,我每次做新项目都会走一遍。别嫌麻烦,数据工程花的时间,会在模型训练阶段加倍还给你。

最后说一句: 数据增强不是越多越好。我见过有人把 10 种增强全堆上,结果模型训练了 3 天还没收敛。先选 2-3 种最有效的,等模型稳定了再慢慢加。这个道理,跟做菜放调料一样——盐放多了,菜就毁了。