3. 数据集构建:从公开数据到私有数据,一场硬仗
说实话,很多人觉得人脸识别最难的是算法。我一开始也这么想。直到我在一个安防项目里,模型在测试集上跑出 99.5% 的准确率,上线第一天就被现场数据打回原形——我才真正明白:数据集才是真正的护城河。
这一章,我就带你走一遍数据集构建的完整流程。从公开数据集怎么选,到私有数据怎么采,再到清洗、标注、增强,每一步都有坑。
3.1 公开数据集:站在巨人肩膀上,但别站歪了
公开数据集是起步的好帮手。但你要清楚,它们各有各的脾气。
| 数据集 | 规模 | 特点 | 适合场景 | 我踩过的坑 |
|---|---|---|---|---|
| LFW | 13,233 张,5749 人 | 自然场景,光照姿态多样 | 算法验证、对比 | 样本太少,容易过拟合 |
| MegaFace | 100 万+ 张,69 万+ 人 | 大规模,含干扰集 | 大规模检索、开集测试 | 噪声多,需要二次清洗 |
| MS-Celeb-1M | 1000 万+ 张,10 万人 | 超大规模,名人数据 | 预训练、骨干网络训练 | 版权争议,部分已下架 |
| VGGFace2 | 330 万+ 张,9131 人 | 姿态、年龄、种族均衡 | 细粒度识别、属性分析 | 下载麻烦,需申请权限 |
我的建议:别只用一个数据集。我习惯用 MS-Celeb-1M 做预训练,用 VGGFace2 做微调,最后用 LFW 做验证。三层组合,效果比单用任何一个都好。
3.2 私有数据采集:从零到一,最难的是第一步
公开数据集再大,也解决不了你的业务场景。比如你做闸机人脸识别,公开数据里哪有俯拍、逆光、戴口罩的样本?
私有数据采集,我总结了三步走:
- 场景定义——先想清楚你的设备装在哪儿。室内还是室外?光线如何?用户配合度怎样?
- 设备选型——摄像头分辨率、帧率、红外/RGB 选择。我做过一个项目,用了 200 万像素的摄像头,结果远距离人脸根本看不清,后来全换了 500 万的。
- 采集策略——分批次、分时段、分人员。别一天拍完,要覆盖不同光照、不同角度、不同表情。
注意隐私合规:采集前必须获得用户知情同意。我曾经因为没处理好授权书,被甲方法务叫去喝茶。现在我的流程是:采集前签协议 → 采集时脱敏 → 存储时加密 → 使用后定期销毁。
3.3 数据清洗:脏数据是模型的天敌
数据采回来,别急着用。先洗一遍。我见过太多团队,模型训不出来,最后发现是数据里混了猫的照片。
清洗流程我一般分四步:
- 去重——用哈希或特征比对,去掉完全相同的图片。同一个人的照片,角度不同可以留,像素级重复必须删。
- 质量过滤——模糊、过暗、过曝、遮挡超过 50% 的,直接扔掉。我常用 Laplacian 算子算清晰度,阈值设 100,低于这个的直接过滤。
- 人脸检测——用 MTCNN 或 RetinaFace 检测人脸区域。检测不到人脸的,或者检测到多张人脸的,标记出来人工处理。
- 标签校验——交叉验证标签是否正确。我习惯让两个人独立标注同一批数据,不一致的交给第三人仲裁。
# 一个简单的质量过滤示例
import cv2
def is_blurry(image_path, threshold=100):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
laplacian_var = cv2.Laplacian(img, cv2.CV_64F).var()
return laplacian_var < threshold
# 使用
if is_blurry("face_001.jpg"):
print("这张太模糊了,扔掉")
3.4 数据标注:标注质量决定模型上限
标注这件事,看着简单,做起来全是坑。我踩过最大的坑是:让外包团队标了 10 万张,回来一看,5% 的标签是错的。
标注规范必须提前定好:
- 人脸框——紧贴人脸,还是留 10% 边距?我建议留 10%,给数据增强留空间。
- 关键点——标 5 点还是 68 点?5 点够用,68 点精度高但成本翻倍。
- 属性标签——年龄、性别、表情、是否戴眼镜。这些对后续模型优化很有用。
- 质量评分——让标注员给每张图打 1-5 分。训练时可以根据分数加权,高质量样本权重更高。
质量控制三板斧:
1. 预标注:先用模型标一遍,人工只修正错误。
2. 抽检:每天抽 10% 的标注结果复查。
3. 反馈闭环:发现错误,及时反馈给标注团队,更新标注规范。
1. 预标注:先用模型标一遍,人工只修正错误。
2. 抽检:每天抽 10% 的标注结果复查。
3. 反馈闭环:发现错误,及时反馈给标注团队,更新标注规范。
3.5 数据增强:让有限的数据发挥无限的价值
数据不够?增强来凑。但增强不是乱加,要有策略。
我常用的增强策略分三类:
| 增强类型 | 具体操作 | 适用场景 | 注意事项 |
|---|---|---|---|
| 几何变换 | 旋转、翻转、缩放、裁剪 | 姿态变化、角度偏移 | 翻转不要过度,人脸不对称 |
| 颜色变换 | 亮度、对比度、饱和度、色相 | 光照变化、不同摄像头 | 不要改变肤色识别特征 |
| 噪声模拟 | 高斯噪声、椒盐噪声、模糊 | 低质量摄像头、远距离 | 噪声强度要适中 |
| 遮挡模拟 | 随机遮挡、口罩、眼镜 | 实际遮挡场景 | 遮挡比例控制在 10%-30% |
我的增强管线:训练时在线增强,每张图随机组合 2-3 种变换。离线增强只做一次,把数据量扩到 3-5 倍。别扩太多,否则数据冗余反而降低模型泛化能力。
3.6 数据集构建全流程:一张图看懂
说了这么多,我把整个流程画成一张图。你照着这个走,基本不会出大问题。
3.7 避坑指南:我替你交过的学费
最后,分享几个我真实踩过的坑。你遇到了,直接绕过去。
坑一:数据分布不均
我曾经只采集了白天的数据,结果模型晚上直接崩了。后来我强制要求:每个场景至少采集 3 个不同时段的样本。
我曾经只采集了白天的数据,结果模型晚上直接崩了。后来我强制要求:每个场景至少采集 3 个不同时段的样本。
坑二:标注标准不统一
外包团队标的人脸框,有的紧贴皮肤,有的留了半个额头。模型学到的全是框的偏差。解决方案:标注前先标 100 张样板,双方对齐标准。
外包团队标的人脸框,有的紧贴皮肤,有的留了半个额头。模型学到的全是框的偏差。解决方案:标注前先标 100 张样板,双方对齐标准。
坑三:增强过度
有一回我把数据扩了 20 倍,模型训练时间长了 5 倍,精度反而掉了 2 个点。后来发现,过度增强引入了太多伪影。现在我的原则是:增强后的数据,人眼还能认出是谁。
有一回我把数据扩了 20 倍,模型训练时间长了 5 倍,精度反而掉了 2 个点。后来发现,过度增强引入了太多伪影。现在我的原则是:增强后的数据,人眼还能认出是谁。
数据集构建,说白了就是一场「质量 vs 数量」的博弈。我的经验是:先追求质量,再追求数量。1000 张精心清洗、标注、增强的数据,比 10000 张粗制滥造的数据强得多。