用 Google 的 FaceNet 做人脸识别---极客帮课程笔记

前几天在极客帮学了一个课程, 应班主任的要求, 做一个笔记;

课程的主要内容是Google开源的机器学习平台 TensorFlow 和人脸识别模型 FaceNet, 这里重点介绍一下人脸识别;

 

1. 环境搭建:

课程的代码运行在 TensorFlow 1.12 版本上的, 下面是 TensorFlow 1.12 版本的环境安装步骤(Win10);

安装 python3.6.8;

安装 cmake;

安装 visual studio c++ 社区版;

安装 pipx:

python -m pip install --user pipx
python -m pipx ensurepath
pipx completions
View Code

用 virtualenv 建立一个隔离的 python 环境, 我们把这个隔离的环境放到 tf 目录下:

pipx install virtualenv
python -m venv tf
virtualenv --system-site-packages -p python3.6 ./tf
View Code

进入我们的隔离环境 tf;

    .\tf\Scripts\activate

安装 TensorFlow:

    pip3 install tensorflow==1.12

安装 python 代码编辑器 jupyter:

    pip3 install jupyter

安装绘图库, keras, opencv 等等:

    pip3 install tensorflow==1.12 
    pip3 install jupyter
    pip3 install matplotlib
    pip3 install pandas
    pip3 install seaborn
    pip3 install numpy
    pip3 install keras==2.1.3
    pip3 install h5py==2.10.0
    pip3 install opencv-python
    pip3 install face_recognition
    pip install sklearn
    pip install dlib==18.17.100
View Code

给 jupyter 安装kernel:

jupyter kernelspec list
python -m ipykernel install --user --name=tf
View Code

运行 jupyter notebook, 就可以打开python 编辑环境了;

 

2. FaceNet人脸识别:

课程里使用 OpenFace 做人脸特征向量提取, OpenFace 是基于2015年 Google 的关于 FaceNet 的论文实现的, 基于深度神经网络;

使用预先训练好的模型, 大概是三百多万张人脸训练出来的模型;

大体逻辑是这样的:

OpenCV读取图片 -> AlignDlib 提取人像 -> 截取人脸 -> 用 OpenFace 提取人脸特征向量 -> 用近邻分类(KNN)将测试的人脸分成不同的人;

我们用杨幂和范冰冰的图片示例一下:

看看代码的运行效果:

用OpenCV 加载一张图片:

 

截取出人脸:

 

打印出原图, AlignDlib检测的人脸坐标, 和截取后的图像:

 

 

 用神经网络获取人脸特征向量, 模型是 OpenFace 训练好的模型, 模型比较复杂, 里面封装了卷积, 池化, 等等的操作; 

 

人脸特征向量保存在 embedded 数组, 每个人脸都被嵌入成了超球面空间上的一个点, 翻译成白话就是128维空间上的一个点;

为什么是128维 --- Google 测试了64维, 128维, 256维... 最终得出结论是 128维空间上准确率最好;

128维空间上的两点之间的距离就是欧式距离, 如果有x1坐标到x128坐标, 欧式距离是两点距离x1差值的平方加上x2差值的平方加上x3差值的平方, 一直累加到x128差值的平方, 然后求和, 再求一个开根号;

我们看看128维空间上两张图片的欧式距离;

 

可以看到, 同一个人的不同照片, 他们在128维空间上的欧式距离很短, 这是因为模型使用 Google 的 Triplet Loss 损失函数训练出来的, 看一下这个损失函数:

 

大体意思是, 一组数据集, 取一个锚点, 对同一个人, 两张图片在128维空间上的欧式距离最远, 对不同的人, 两张图片在128维空间上欧式距离最近 , 加上阈值, 得到损失值, 将损失值反馈到神经网络, 由神经网络来调整权重;

128维欧式空间距离很短两个点, 小于阈值, 我们认为就是同一个人;

对得到的128维的人脸特征向量, 我们可以用 KNeighborsClassifier 来分类, 度量指标是欧几里得距离, 就是欧式距离;

 

KNeighborsClassifier (邻近算法) 的大体意思就是近邻分类, 距离比较近的一组点分到一个类别中;

我们找一个测试图片看看效果:

 

对于128维空间上的点, 我们无法观测, 我们可以借助一些降维工具来辅助, 列如 TSNE;

我们用 TSNE 把杨幂和范冰冰128维空间上的点降维到3维空间看看(杨幂和范冰冰分别有10张图片, 在128维空间上分别有10个点):

 

三维空间观测起来有点费力气, 我们再降到2维空间试试:

 

可以看到, 这些点的分布并不是很理想; 原因是和 OpenFace 的训练集有关系, 感兴趣的小伙伴可以自己研究;

 

后记:

FaceNet 提取出来的人脸特征向量是128维的向量, 除了分类, 还可以做相似搜索之类的东西, 比如利用一些向量数据库做检索, 可以判断哪些人长得像;

 

 

posted on 2021-12-02 20:50  聆听风琴的巴赫  阅读(837)  评论(0编辑  收藏  举报

导航