【PaddleClas】手把手让你训练自己的人脸识别模型

在这里插入图片描述

简介

在这个项目中,我们将介绍如何使用PaddleClas仓库训练我们自己的AdaFace模型,为以后的人脸识别做铺垫。在AIStudio中,项目空间大小只有100G,如果你想要在本地训练更大的数据集请访问我的Github仓库

模型

AdaFace简介

在这里插入图片描述

一直以来,低质量图像的人脸识别都具有挑战性,因为低质量图像的人脸属性是模糊和退化的。将这样的图片输入模型时,将不能很好的实现分类。而在人脸识别任务中,我们经常会利用opencv的仿射变换来矫正人脸数据,这时数据会出现低质量退化的现象。如何解决低质量图片的分类问题成为了模型落地时的痛点问题。

在AdaFace这项工作中,作者在损失函数中引入了另一个因素,即图像质量。作者认为,强调错误分类样本的策略应根据其图像质量进行调整。具体来说,简单或困难样本的相对重要性应该基于样本的图像质量来给定。据此作者提出了一种新的损失函数来通过图像质量强调不同的困难样本的重要性。

由上,AdaFace缓解了低质量图片在输入网络后输出结果精度变低的情况,更加适合在人脸识别任务落地中使用。

AdaFace在不同数据集的验证集上的效果

Arch Dataset Method LFW CFPFP CPLFW CALFW AGEDB AVG
R18 CASIA-WebFace AdaFace 0.9913 0.9259 0.8700 0.9265 0.9272 0.9282
R18 VGGFace2 AdaFace 0.9947 0.9713 0.9172 0.9390 0.9407 0.9526
R18 WebFace4M AdaFace 0.9953 0.9726 0.9228 0.9552 0.9647 0.9621
R50 CASIA-WebFace AdaFace 0.9942 0.9641 0.8997 0.9323 0.9438 0.9468
R50 MS1MV2 AdaFace 0.9982 0.9786 0.9283 0.9607 0.9785 0.9688
R50 WebFace4M AdaFace 0.9978 0.9897 0.9417 0.9598 0.9778 0.9734
R100 MS1MV2 AdaFace 0.9982 0.9849 0.9353 0.9608 0.9805 0.9719
R100 MS1MV3 AdaFace 0.9978 0.9891 0.9393 0.9602 0.9817 0.9736
R100 WebFace4M AdaFace 0.9980 0.9917 0.9463 0.9605 0.9790 0.9751
R100 WebFace12M AdaFace 0.9982 0.9926 0.9457 0.9612 0.9800 0.9755

数据集

V1.2更新中,我们将数据集更新到使用MS1MV2,这个数据集非常大,训练比较慢,想要使用CASIA-WebFace的同学,请修改项目数据集。

训练集

CASIA-WebFace

简介: CASIA-WebFace数据集包含了10575 个人的494414 张图像。CASIA-webface数据库,压缩包有4个多g,里面包含了10000个人,一共50万张人脸图片,无论是做SVM,DNN还是别的训练,都是非常好的数据库。在这个项目中,我们使用的数据集为insightface制作的112x112对齐过后的数据集,下载地址为:CASIA-WebFace。要注意的是,该数据集是用mxnet来进行读取的,但是在AIStudio中不能使用这个包,因此我把图片导出并上传到了Aistudio的CASIA-webface数据集提供给大家下载。

链接: AIStudio

MS1MV2

简介: MS1MV2数据集是微软发布的数据集,大概有85000个不同的人的380万张照片。但是前段时间微软已经宣布撤回不再提供下载。

链接: AIStudio

验证集

AgeDB-30

AgeDB(Age Database )包含6000对 共440个ID,12240张不同姿态、表情、年龄、性别的图片。同一个ID中,最大最小年龄差分别为3岁和101岁,所有ID的平均年龄为49岁。根据不同的年龄差把所有数据划分为4个年龄段(年龄差5岁、10岁、20岁以及30岁)。其中每个年龄段的数据包括300对正样本、300对负样本。此处验证集使用年龄差为30的数据,命名为agedb30。

LFW

5749个ID,13233张不同姿态、表情的图片,提供的人脸图片均来源于生活中的自然场景LFW数据集主要测试人脸识别的准确率,该数据库从中随机选择了6000对人脸组成了人脸辨识图片对,其中3000对属于同一个人2张人脸照片,3000对属于不同的人每人1张人脸照片。测试过程LFW给出一对照片,询问测试中的系统两张照片是不是同一个人,系统给出“是”或“否”的答案。通过6000对人脸测试结果的系统答案与真实答案的比值可以得到人脸识别准确率。

CALFW

基于LFW数据集标注的跨年龄数据集

CPLFW

基于LFW数据集标注的跨姿态数据集

CFP

这个数据集由500个identity的约共7000张图片组成,这个数据集的特别之处在于对于每个人,它有10张正面图像和4张侧面图像,这对于想要做侧脸识别的同学还是很有帮助的。

项目改进部分(参考的仓库都会在后面的部分标注出来)

感谢HydrogenSulfate同学在我训练和改进AdaFace时提供的无私帮助,飞桨的同学都太友好了,感受到了满满的爱。

  • 改进一:PaddleClas自带的AdaFace读取数据集时,使用的读取方式和AdaFace原仓库一样,这部分代码由于是内部复现,存在部分缺失,这对在AIStudio上的用户来说并不友好。我参考PaddleClas原读取数据集的方式,重写了这部分代码。同时,我也自己制作了对应的数据集,上传到了AIStudio。
  • 改进二:PaddleClas自带的AdaFace使用的backbone是IR18,训练完模型大小足足234M,这对实际落地并不友好,我改成使用MobileFacenet作为Backbone。这部分的优化让模型精度几乎不变的情况下,更小,速度更快!!!!
  • 改进三:参考原仓库,新增了转换数据集的代码

训练前的准备工作

在训练开始前,我们要准备一下数据集,并且安装一下需要的环境

如何自己转换数据集

详情请查看简介中的Github仓库,在dataset/README.md文件中有介绍。

解压数据集

开始训练之前我们要先下载PaddleClas和训练所需要的数据集。如果你没有下载,请运行紧跟着这个markdown块的下一个代码来解压数据集

# 以下为CASIA-WebFace数据集的配置
# 解压数据集,这里可以根据自己的需求选择不同的数据集进行训练
# !unzip -qo ~/data/data167537/face_webface_paddle_clas.zip -d ~/work/PaddleFaceRecognition/dataset

# 以下为MS1MV2数据集的配置
# 解压数据集,这里可以根据自己的需求选择不同的数据集进行训练
%cd ~/data/data168426
!cat faces_emore* > myzip.tar.gz
!tar -zxvf ~/data/data168426/myzip.tar.gz -C ~/work/PaddleFaceRecognition/dataset > /dev/null
!rm -rf ~/data/data168426/myzip.tar.gz

安装训练所需要的环境

# 进入项目目录
%cd ~/work/PaddleFaceRecognition

# 安装所需要的环境
!pip install -r ./requirements.txt

训练我们的模型

自定义训练配置

PaddleClas的config文件可以让大家自由配置训练方法,我这里给出我在训练MobileFacenet为backbone时做的调整。

  • 调整一:原仓库使用的batch_size为256,我这里修改为512,训练的更快。
  • 调整二:原仓库所使用的学习策略分别在[12, 20, 24],三个回合进行学习率的下降。但是经过我在数据集上的测试,如果是0.1的学习率在第9回合之前,模型的精确度就没办法得到很好的提升了,因此我将学习策略改成[10, 16, 22],让模型更快的下降。

开始训练

# 进入项目目录
%cd ~/work/PaddleFaceRecognition

# 训练MobileFacenet版本的模型

# 首次训练请运行以下代码
# !export CUDA_VISIBLE_DEVICES=0
# !python3 -m paddle.distributed.launch --gpus="0" \
#         ./tools/paddle_clas_train.py \
#         -c ./configs/ada_face/adaface_mobile_facenet_128_ms1mv2.yaml \
#         -o Global.use_visualdl=True

# 继续训练请运行以下代码
!export CUDA_VISIBLE_DEVICES=0
!python3 -m paddle.distributed.launch --gpus="0" \
        ./tools/paddle_clas_train.py \
        -c ./configs/ada_face/adaface_mobile_facenet_128_ms1mv2.yaml \
        -o Global.use_visualdl=True \
        -o Global.checkpoints="./output/RecModel/latest"

对模型进行进行评估

训练完成后,如果我们想要查看我们训练好的,精度最高的模型精度有多高,就需要评估。

运行评估后,我的日志如下:

[2022/09/09 05:52:30] ppcls INFO: [Eval][Epoch 0][Avg], agedb_30_test_acc: 0.92233, agedb_30_test_best_threshold: 1.64800, agedb_30_num_test_samples: 12000.00000, cfp_fp_test_acc: 0.93157, cfp_fp_test_best_threshold: 1.69900, cfp_fp_num_test_samples: 14000.00000, lfw_test_acc: 0.99117, lfw_test_best_threshold: 1.52800, lfw_num_test_samples: 12000.00000, cplfw_test_acc: 0.86600, cplfw_test_best_threshold: 1.65900, cplfw_num_test_samples: 12000.00000, calfw_test_acc: 0.92667, calfw_test_best_threshold: 1.57200, calfw_num_test_samples: 12000.00000, all_test_acc: 0.92755

由上,我训练的模型精度如下:

Arch Dataset Method LFW CFPFP CPLFW CALFW AGEDB AVG
我的R18 CASIA-WebFace AdaFace 0.99117 0.90671 0.86600 0.92667 0.92233 0.92755
原论文R18 CASIA-WebFace AdaFace 0.9913 0.9259 0.8700 0.9265 0.9272 0.9282

可以看到,虽然并没有达到原论文的精度,但是几乎相差不多.

开始评估

# 进入项目目录
%cd ~/work/PaddleFaceRecognition

# 注意: !!!!!!配置文件,模型,数据集需要对应的上才行!!!!!
!export CUDA_VISIBLE_DEVICES=0
!python3 -m paddle.distributed.launch \
    tools/paddle_clas_eval.py \
        -c ./configs/ada_face/adaface_mobile_facenet_128_ms1mv2.yaml \
        -o Global.pretrained_model=./output/RecModel/best_model

导出模型

这里导出模型我分为两类,一种是静态图模型,一种是onnx模型,以下分别给出了导出的方法

导出PaddleInference模型

PaddleInference模型是静态图模型,运行下面的代码导出模型。

# 进入项目目录
%cd ~/work/PaddleFaceRecognition
!python tools/paddle_clas_export_model.py \
    -c ./configs/ada_face/adaface_mobile_facenet_128_ms1mv2.yaml \
    -o Global.pretrained_model=./output/RecModel/best_model \
    -o Global.save_inference_dir=./output/paddle_inference/adaface \
    -o Global.image_shape="[3,112,112]"

导出为ONNX模型

# 进入项目目录
%cd ~/work/PaddleFaceRecognition

from ppcls.arch.backbone.model_zoo.mobile_facenet import MobileFaceNet_128
import paddle

# 实例化模型
model = MobileFaceNet_128(num_features=512)

# 读取权重文件
weights = paddle.load("./output/RecModel/best_model.pdparams")
new_weights = {}
for key,value in weights.items():
    new_weights[key.replace("backbone.","")] = value
model.set_state_dict(new_weights)

# 将模型设置为推理状态
model.eval()

# 定义输入数据
input_spec = paddle.static.InputSpec(shape=[1, 3, 112, 112], dtype='float32', name='image')

paddle.onnx.export(model, './output/paddle_inference/adaface/adaface', input_spec=[input_spec], opset_version=10, enable_onnx_checker=True)

我训练好的模型精度表

Arch Dataset Method LFW CFPFP CPLFW CALFW AGEDB AVG
R18 CASIA-WebFace AdaFace 0.99117 0.90671 0.86600 0.92667 0.92233 0.92755
mobileFacenet CASIA-WebFace AdaFace 0.99000 0.91243 0.84783 0.91883 0.91917 0.91765
mobileFacenet MS1MV2 AdaFace 0.99417 0.92229 0.88250 0.95200 0.95767 0.94172

空间有限,想要不同的模型请从我的百度网盘上直接下载
链接: https://pan.baidu.com/s/1VV-st4oDOr46cbav5ql8iA?pwd=6666 提取码: 6666
–来自百度网盘超级会员v5的分享

更新进度(总结)

记录一下更新进度

V0.0

  • 2022-09-02
    • 用paddle复现了原论文的数据集分解过程
    • 修复PaddleClas缺少生成mem文件代码的问题
  • 2022-09-03
    • 编写新的读取训练集的方法
    • 开始尝试训练模型,并且写了初版的jupyernotebook
  • 2022-09-04
    • 训练中断,HydrogenSulfate提供了读取断点的文档,在jupyernotebook中更新了如何读取断点的方法
  • 2022-09-07
    • 完成训练
    • 完成评估部分的编写
    • 完成jupyernotebook的编写
    • 生成第一个版本

V0.1
2022-09-09

  • insightface上找到了从数据集中提取图片的方式,现在只提取训练集图片。需要注意的是这个脚本不能在AIStudio上运行,如果你需要从头下载数据集,请从我的github仓库中下载源码,并参考dataset/README.md文档进行操作
  • 重写了验证集读取5个数据集的代码,现在能直接从bin文件生成mem文件
  • 数据集重新上传了一个小型化的数据集,方便在AIStudio中解压,同时占用更少的内存空间
  • 缩减了需要的requirements
  • 修复了V0.0版本验证时精度偏小的问题

V1.0 -> 2022-09-09

更新内容:

  • 修复dataset/README.md文档的错误
  • 修正了jupyter-notebook中训练部分代码的错误
  • 新增MobileFacenet backbone
  • 整理了一下jupyter-notebook
  • 修复V0.0config配置文件的错误

V1.1 -> 2022-09-10

更新内容:

  • 修复部分小bug
  • jupyter-notebook排版进行更新,对读者更友好。

V1.2 -> 2022-09-12

更新内容:

  • 修复部分文档错误
  • 新增使用MS1SMV2数据集的训练的内容,精度再次提升
  • 修正jupyter-notebook内容,细分了几个板块,对新手更友好

V1.3 -> 2022-09-13

更新内容:

  • 修复文档错误
  • 新增导出PaddleInference和ONNX模型的代码

V1.4 -> 2022-09-26

更新内容:

  • 清空无用的输出

项目参考

论文

AdaFace原论文地址

MobileFacenet原论文地址

代码参考仓库地址

AdaFace原仓库地址

PaddleClas仓库地址

insightface仓库地址

联系方式

如果运行过程中出现了问题,请通过邮件联系我。

邮件地址: zheng_bicheng@outlook.com

请点击此处查看本环境基本用法.

Please click here for more detailed instructions.

此文章为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐