用 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維的向量, 除了分類, 還可以做相似搜索之類的東西, 比如利用一些向量數據庫做檢索, 可以判斷哪些人長得像;

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM