使用RetinaFace及FaceNet实现人脸识别

7/29/2022 RetinaFaceFaceNetDeepface人脸检测人脸特征提取及匹配

# 1. 前言

# 1.1 人脸检测与人脸识别

人脸检测是对人脸进行识别和处理的第一步,主要用于检测并定位图片中的人脸,返回高精度的人脸框坐标及人脸特征点坐标。人脸识别会进一步提取每个人脸中所蕴涵的身份特征,并将其与已知的人脸进行对比,从而识别每个人脸的身份。目前人脸检测 / 识别的应用场景逐渐从室内演变到室外,从单一限定场景发展到广场、车站、地铁口等场景,人脸检测 / 识别面临的要求也越来越高,比如:人脸尺度多变、数量冗大、姿势多样包括俯拍人脸、戴帽子口罩等的遮挡、表情夸张、化妆伪装、光照条件恶劣、分辨率低甚至连肉眼都较难区分等。随着深度学习的发展,基于深度学习技术的人脸检测 / 识别方法取得了巨大的成功,本文主要介绍人脸检测的深度学习算法 RetinaFace 和人脸识别的深度学习算法 FaceNet。

# 1.2 RetinaFace人脸检测

Retinaface是Insightface团队在2019年提出的新人脸检测模型,该模型在 WiderFace 数据集上刷新了AP。原模型使用mxnet框架进行搭建,目前社区也有其他框架复现的版本,其中最让人熟知的莫过于Pytorch版的Retinaface。Retinaface是基于检测网络RetinaNet的改进版,添加了SSH网络的三层级联检测模块,提升检测精度。

RetinaFace人脸检测简介

论文原文:https://arxiv.org/pdf/1905.00641.pdf (opens new window)

项目地址1(MXNet实现):https://github.com/deepinsight/insightface/tree/master/RetinaFace (opens new window)

项目地址2(Pytorch实现):https://github.com/biubug6/Pytorch_Retinaface (opens new window)(本文示例使用这个)

预训练模型:https://drive.google.com/open?id=1oZRSG0ZegbVkVwUd8wUIQx8W7yfZ_ki1 (opens new window)

# 1.3 FaceNet人脸特征提取及匹配

Google工程师Florian Schroff,Dmitry Kalenichenko,James Philbin提出了人脸识别FaceNet模型,该模型没有用传统的softmax的方式去进行分类学习,而是抽取其中某一层作为特征,学习一个从图像到欧式空间的编码方法,然后基于这个编码再做人脸识别、人脸验证和人脸聚类等。

FaceNet主要用于验证人脸是否为同一个人,通过人脸识别这个人是谁。FaceNet的主要思想是把人脸图像映射到一个多维空间,通过空间距离表示人脸的相似度。同个人脸图像的空间距离比较小,不同人脸图像的空间距离比较大。这样通过人脸图像的空间映射就可以实现人脸识别,FaceNet中采用基于深度神经网络的图像映射方法和基于triplets(三联子)的loss函数训练神经网络,网络直接输出为128维度的向量空间。

FaceNet的网络结构如下图所示,其中Batch表示人脸的训练数据,接下来是深度卷积神经网络,然后采用L2归一化操作,得到人脸图像的特征表示,最后为三元组(Triplet Loss)的损失函数。

FaceNet人脸识别简介

论文原文:https://arxiv.org/pdf/1503.03832.pdf (opens new window)

项目地址:https://github.com/davidsandberg/facenet (opens new window)

预训练模型:facenet的原作者提供了两个预训练的模型,分别是基于CASIA-WebFace和VGGFace2人脸库训练的。

Model name LFW accuracy Training dataset Architecture
20180408-102900 (opens new window) 0.9905 CASIA-WebFace Inception ResNet v1 (opens new window)
20180402-114759 (opens new window) 0.9965 VGGFace2 Inception ResNet v1 (opens new window)

# 2. 封装部署人脸识别服务

# 2.1 本地运行RetinaFace人脸检测官方示例

在本地使用Mac运行测试程序,用CPU运行,使用官方的预训练模型,不自己训练模型了。

  • PC型号及配置:Macbook Pro2021,M1Pro芯片,16GB内存,512GB存储

  • 系统版本:macos Monterey 12.6

Step1:下载 源码 (opens new window)预训练模型 (opens new window)(放在 Retinaface_model_v2 目录里)并安装项目依赖,项目结构如下:

.
├── LICENSE.MIT
├── README.md
├── Retinaface_model_v2
│   ├── Resnet50_Final.pth
│   ├── mobilenet0.25_Final.pth
│   └── mobilenetV1X0.25_pretrain.tar
├── convert_to_onnx.py
├── curve
├── data
├── detect.py
├── layers
├── models
├── test_fddb.py
├── test_widerface.py
├── train.py
├── utils
└── widerface_evaluate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Step2:修改一下参数并运行人脸检测程序detect.py

parser = argparse.ArgumentParser(description='Retinaface')

parser.add_argument('-m', '--trained_model', default='./Retinaface_model_v2/Resnet50_Final.pth',
                    type=str, help='Trained state_dict file path to open')   # 默认路径为 ./weights/Resnet50_Final.pth
parser.add_argument('--network', default='resnet50', help='Backbone network mobile0.25 or resnet50')
parser.add_argument('--cpu', action="store_true", default=True, help='Use cpu inference')   # 默认False,由于用不了GPU,就改成CPU运行
parser.add_argument('--confidence_threshold', default=0.02, type=float, help='confidence_threshold')
parser.add_argument('--top_k', default=5000, type=int, help='top_k')
parser.add_argument('--nms_threshold', default=0.4, type=float, help='nms_threshold')
parser.add_argument('--keep_top_k', default=750, type=int, help='keep_top_k')
parser.add_argument('-s', '--save_image', action="store_true", default=True, help='show detection results')
parser.add_argument('--vis_thres', default=0.6, type=float, help='visualization_threshold')
args = parser.parse_args()
1
2
3
4
5
6
7
8
9
10
11
12
13

程序运行起来后,会用curve目录里的test.jpg作为测试文件,生成效果如下:

测试RetinaFace人脸检测

# 2.2 封装成特定人物识别服务

# 2.2.1 目录结构及使用说明

使用 Flask 将 RetinaFace 和 FaceNet 封装成特定人物识别服务,代码我已在Github上开源。

项目目录结构如下:

.
├── core    // 核心算法模块(包括 RetinaFace 和 FaceNet 及相关处理)
│   ├── data
│   │   ├── __init__.py
│   │   ├── config.py
│   │   ├── data_augment.py
│   │   └── wider_face.py
│   ├── facenet
│   │   ├── facenet.py
│   │   ├── get_database_vector.py
│   │   └── start_facenet.py
│   ├── layers
│   │   ├── __init__.py
│   │   ├── functions
│   │   └── modules
│   ├── models   // 算法模型
│   │   ├── Retinaface_model_v2
│   │   ├── facenet
│   │   ├── net.py
│   │   └── retinaface.py
│   ├── save_face_database  // 人脸底库
│   │   ├── baideng
│   │   └── telangpu
│   ├── utils
│   │   ├── box_utils.py
│   │   ├── compare_vector.py
│   │   ├── nms
│   │   └── timer.py
│   └── face_identify.py  // 人脸识别服务的主入口(用于给Flask调用)
├── log.py
├── code.py
├── response.py
├── server.py         // 使用Flask封装好的服务
└── server_test.py    // 测试服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

使用说明:

  • [1] 运行环境:项目代码里我使用的是CPU运行方式。如果有GPU,可以修改一下配置,将其改成GPU方式运行(需要注意的是,PyTorch 及 Tensorflow 的依赖需要安装对应GPU版本的)。

  • [2] 人脸底库更换:人脸底库放在 save_face_database 目录,制作人脸底库的时候注意只保留人脸,左侧脸30度+右侧脸30度+正脸各2张,更换人脸底库后,需要修改一下 face_identify.py 程序的配置,将如下配置改成自己的。

    database_path = 'core/save_face_database'
    vector_database = get_all_basedata(database_path)
    dic_info_person = {}
    dic_info_person['baideng'] = ['拜登']
    dic_info_person['telangpu'] = ['特朗普']
    
    1
    2
    3
    4
    5

# 2.2.2 测试运行特定人物识别的服务

安装好依赖之后,先启动 server.py 服务,再执行 server_test.py 即可本地测试。

$ python3 server.py 
$ python3 server_test.py
1
2

测试效果如下:

测试运行特定人物识别的服务

# 2.3 Docker部署特定人物识别服务

# 2.3.1 编写Dockerfile及部署脚本

Dockerfile

# 基于python3.7镜像创建新镜像
FROM python:3.7
# 创建容器内部目录
RUN mkdir /code
ADD . /code/
WORKDIR /code
# 安装项目依赖
# RUN export https_proxy=http://xxx.xxx.xxx.xxx:xxx   # 国内服务器建议设置代理
RUN apt update && apt install libgl1-mesa-glx -y
RUN pip install torch==1.10.0+cpu torchvision==0.11.1+cpu torchaudio==0.10.0+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
RUN wget https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow_cpu-2.6.0-cp37-cp37m-manylinux2010_x86_64.whl
RUN pip install https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow_cpu-2.6.0-cp37-cp37m-manylinux2010_x86_64.whl
RUN rm -f tensorflow_cpu-2.6.0-cp37-cp37m-manylinux2010_x86_64.whl
RUN pip install Flask==2.0.2
RUN pip install Flask_Cors==3.0.10
RUN pip install pre_request==2.1.5
RUN pip install opencv_python==4.4.0.46
RUN pip install numpy==1.19.5
RUN pip install scikit_learn==1.0.2
# 放行端口
EXPOSE 5007
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

install.sh

#!/bin/bash
docker build -t face_identify_image .
docker run -itd -p 5007:5007 --name face_identify -e TZ="Asia/Shanghai" face_identify_image:latest
1
2
3

# 2.3.2 服务器上使用Docker部署服务

服务器环境:Debian 11 x86_64 系统,8GB内存,160GB存储,2x Intel Xeon CPU,无GPU,带宽1 Gigabit,Docker version 20.10.17

部署测试:将整个项目上传到服务器上,执行 install.sh 安装脚本,部署成功后改一下 server_test.py 的 IP 对其进行功能测试。正式部署使用nohup后台运行。

$ chmod u+x install.sh && ./install.sh
$ docker exec -it face_identify /bin/bash
$ python server.py
1
2
3

docker打包成功

性能指标及资源占用:接口请求速度约2.5s(包含网络请求的损耗),存储占用约4.15GB,内存占用约1.72GB。

$ docker images                            // 查看镜像的占用空间
$ docker stats --no-stream face_identify   // 查看容器的CPU、内存等指标占用率(不带 --no-stream 参数的话可以实时刷新)
1
2

运行算法的系统资源占用

# 3. Deepface人脸识别和分析

# 3.1 Deepface概述及安装

# 3.1.1 Deepface简介

Deepface是一个用于Python的轻量级面部识别和面部属性分析(年龄,性别,情绪和种族)框架。它是一个混合面部识别框架,包装了最先进的模型:VGG-Face, Google FaceNet, OpenFace, Facebook DeepFace, DeepID, ArcFace, Dlib 和 SFace。实验显示,人类在面部识别任务上的准确率为97.53%,而这些模型已经达到并超过了该准确度水平。

项目地址:https://github.com/serengil/deepface (opens new window)

deepface

# 3.1.2 Deepface安装

可以通过pip、conda、源码等方式安装,我这里采用了源码安装的方式,所需的模型会在之后首次运行时自动下载。

// 方式一
$ pip3 install deepface

// 方式二
$ conda install -c conda-forge deepface

// 方式三
$ git clone https://github.com/serengil/deepface.git
$ cd deepface
$ pip3 install -e .
1
2
3
4
5
6
7
8
9
10

# 3.2 Deepface使用示例

在该项目的 ./tests/dataset目录下,有很多测试数据,下面的使用示例就使用这些数据。

# 3.2.1 验证人脸是否同一人

这个用来验证面部配对为同一人或不同的人,它需要精确的图像路径作为输入,也支持传递numpy或base64编码的图像。

# -*- coding: utf-8 -*-

from deepface import DeepFace

result = DeepFace.verify(img1_path="tests/dataset/img1.jpg", img2_path="tests/dataset/img2.jpg")
print(result)

>>> 输出结果
{
    'verified': True,
    'distance': 0.25551901561553336,
    'threshold': 0.4,
    'model': 'VGG-Face',
    'detector_backend': 'opencv',
    'similarity_metric': 'cosine',
    'facial_areas': {
        'img1': {
            'x': 345,
            'y': 211,
            'w': 769,
            'h': 769
        },
        'img2': {
            'x': 516,
            'y': 192,
            'w': 512,
            'h': 512
        }
    },
    'time': 2.14
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 3.2.2 面部属性分析

Deepface还配备了强大的面部属性分析模块,包括年龄、性别、面部表情(包括愤怒、恐惧、中立、悲伤、厌恶、快乐和惊讶)以及种族(包括亚洲人,白人,中东人,印度人,拉丁美洲人和黑人)预测。性别模型的准确度为 97.44%,精确度为 96.29%,召回率为 95.05% 。

# -*- coding: utf-8 -*-

from deepface import DeepFace

objs = DeepFace.analyze(img_path="tests/dataset/img4.jpg", actions=['age', 'gender', 'race', 'emotion'])
print(objs)

>>> 输出结果
[
    {
        'age': 31,
        'region': {
            'x': 419,
            'y': 301,
            'w': 919,
            'h': 919
        },
        'face_confidence': 10.600495017308276,
        'gender': {
            'Woman': 99.99980926513672,
            'Man': 0.0001894966089821537
        },
        'dominant_gender': 'Woman',
        'race': {
            'asian': 0.05465123616591261,
            'indian': 0.08727372165672818,
            'black': 0.0038303477576379545,
            'white': 91.42375690653837,
            'middleeastern': 5.098592254687279,
            'latinohispanic': 3.3318944028741835
        },
        'dominant_race': 'white',
        'emotion': {
            'angry': 0.0634299241937697,
            'disgust': 2.502598874798423e-05,
            'fear': 0.16904905205592513,
            'happy': 92.4351155757904,
            'sad': 0.4689138848334551,
            'surprise': 0.23647076450288296,
            'neutral': 6.626990437507629
        },
        'dominant_emotion': 'happy'
    }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 4. 参考资料

[1] 人脸算法系列(二):RetinaFace论文精读 from 腾讯云 (opens new window)

[2] Retinaface论文翻译及理解 from 知乎 (opens new window)

[3] 聪明的人脸识别4——Pytorch 利用Retinaface+Facenet搭建人脸识别平台 from CSDN (opens new window)

[4] 人脸检测之Retinaface算法:论文阅读及源码解析 from CSDN (opens new window)

[5] 从零开始学人脸检测之Retinaface篇(内含魔改版GhostNet+mbv2)from 知乎 (opens new window)

[6] 人脸检测:RetinaFace from CodeAntenna (opens new window)

[7] RetinaFace人脸检测简要介绍 from CSDN (opens new window)

[8] Pytorch-RetinaFace 详解 from 知乎 (opens new window)

[9] 人脸检测算法(一)from 知乎 (opens new window)

[10] 人脸检测算法综述 from 知乎 (opens new window)

[11] InsightFace力作:RetinaFace单阶段人脸检测器 from giantpandacv (opens new window)

[12] 适合ARM 的轻量级人脸检测算法汇总 from CSDN (opens new window)

[13] 如何应用 MTCNN 和 FaceNet 模型实现人脸检测及识别 from InfoQ (opens new window)

[14] 谷歌人脸识别系统FaceNet解析 from 知乎 (opens new window)

[15] 利用MTCNN和facenet实现人脸检测和人脸识别 from CSDN (opens new window)

[16] FaceNet源码解读:史上最全的FaceNet源码使用方法和讲解(一)(附预训练模型下载) from CSDN (opens new window)

[17] 新版本tensorflow无法使用GPUoptions from CSDN (opens new window)

[18] 关于出现Object arrays cannot be loaded when allow_pickle=False报错的解决方法 from CSDN (opens new window)

[19] “属性错误:'int'对象没有属性'值'”是什么意思?你如何修复它(python、tensorflow、tensorflow2.0、开发)from Quora (opens new window)

[20] import tensorflow.compat.v1 as tf报错,无compat module解决办法 from CSDN (opens new window)

Last Updated: 5/4/2025, 4:42:45 PM