人脸验证 DeepID 算法实践
人臉驗證 DeepID 算法實踐
4,610 次閱讀 -?文章作者:雨石? 出處:雨石的博客
目前人臉驗證算法可以說是DeepID最強,本文使用theano對DeepID進行實現。關于deepid的介紹,可以參見我這一片博文?DeepID之三代。
當然DeepID最強指的是DeepID和聯合貝葉斯兩個算法,本文中只實現了DeepID神經網絡,并用它作為特征提取器來應用在其他任務上。
本文所用到的代碼工程在github上:DeepID_FaceClassify,如果這篇博客幫到了你,求star。咳咳,為了github工程的star數我覺得我太無恥了,哈哈。
實踐流程
?環境配置
本工程使用theano庫,所以在實驗之前,theano環境是必須要配的,theano環境配置可以參見theano document。文檔已經較為全面,本文不再贅述,在下文中,均假設讀者已經裝好了theano。
代碼概覽
本文所用到的代碼結構如下:
| 1234567891011 | src/├── conv_net│?? ├── deepid_class.py│?? ├── deepid_generate.py│?? ├── layers.py│?? ├── load_data.py│?? └── sample_optimization.py└── data_prepare????├── vectorize_img.py????├── youtube_data_split.py????└── youtube_img_crop.py |
正如文件名命名所指出的,代碼共分為兩個模塊,即數據準備模塊(data_prepare)和卷積神經網絡模塊(conv_net)。
數據準備
我覺得DeepID的強大得益于兩個因素,卷積神經網絡的結構和數據,數據對于DeepID或者說對任何的卷積神經網絡都非常重要。
可惜的是,我去找過論文作者要過數據,可是被婉拒。所以在本文的實驗中,我使用的數據并非論文中的數據。經過下面的描述你可以知道,如果你還有其他的數據,可以很輕松的用python將其處理為本文DeepID網絡的輸入數據。
以youtube face數據為例。它的文件夾結構如下所示,包含三級結構,第一是以人為單位,然后每個人有不同的視頻,每個視頻中采集出多張人臉圖像。
| 1 2 3 4 5 6 7 8 | youtube_data/ ├──people_folderA │??├──video_folderA │??│??├──img1.jpg │??│??├──img2.jpg │??│??└──imgN.jpg │??└──video_folderB └──people_folderB |
拿到youtube face數據以后,需要做如下兩件事:
- 對圖像進行預處理,原來的youtube face圖像中,人臉只占中間很小的一部分,我們對其進行裁剪,使人臉的比例變大。同時,將圖像縮放為(47,55)大小。
- 將數據集合劃分為訓練集和驗證集。本文中劃分訓練集和驗證集的方式如下:
- 對于每一個人,將其不同視頻下的圖像混合在一起
- 隨機化
- 選擇前5張作為驗證集,第6-25張作為訓練集。
經過劃分后,得到7975張驗證集和31900訓練集。顯然,根據這兩個數字你可以算出一共有1595個類(人)。
數據準備的代碼使用
注意:?數據準備模塊中以youtube為前綴的的程序是專門用來處理youtube數據,因為其他數據可能圖像屬性和文件夾的結構不一樣。如果你使用了其他數據,請閱讀youtube_img_crop.py和youtube_data_split.py代碼,然后重新寫出適合自己數據的代碼。數據預處理代碼都很簡單,相信在我代碼的基礎上,不需要改太多,就能適應另一種數據了。
youtube_img_crop.py
被用來裁剪圖片,youtube face數據中圖像上人臉的比例都相當小,本程序用于將圖像的邊緣裁減掉,然后將圖像縮放為47×55(DeepID的輸入圖像大小)。
| 12 | Usage: python youtube_img_crop.py aligned_db_folder new_folder |
- aligned_db_folder: 原始文件夾
- new_folder: 結果文件夾,與原始文件夾的文件夾結構一樣,只不過圖像是被處理后的圖像。
youtube_data_split.py
用來切分數據,將數據分為訓練集和驗證集。
| 1 2 | Usage:pythonyoutube_data_split.pysrc_foldertest_set_filetrain_set_file |
- src_folder: 原始文件夾,此處應該為上一步得到的新文件夾
- test_set_file: 驗證集圖片路徑集合文件
- train_set_file: 訓練集圖片路徑集合文件
test_set_file和train_set_file的格式如下,每一行分為兩部分,第一部分是圖像路徑,第二部分是圖像的類別標記。
| 1234 | youtube_47_55/Alan_Ball/2/aligned_detect_2.405.jpg,0youtube_47_55/Alan_Ball/2/aligned_detect_2.844.jpg,0youtube_47_55/Xiang_Liu/5/aligned_detect_5.1352.jpg,1youtube_47_55/Xiang_Liu/1/aligned_detect_1.482.jpg,1 |
vectorize_img.py
用來將圖像向量化,每張圖像都是47×55的,所以每張圖片變成一個47×55×3的向量。
為了避免超大文件的出現,本程序自動將數據切分為小文件,每個小文件中只有1000張圖片,即1000×(47×55×3)的矩陣。當然,最后一個小文件不一定是1000張。
| 1 2 | Usage:pythonvectorize_img.pytest_set_filetrain_set_filetest_vector_foldertrain_vector_folder |
- test_set_file:?*_data_split.py生成的
- train_set_file:?*_ata_split.py生成的
- test_vector_folder: 存儲驗證集向量文件的文件夾名稱
- train_vector_folder: 存儲訓練集向量文件的文件夾名稱
Conv_Net
走完了漫漫前路,終于可以直搗黃龍了。現在是DeepID時間。吼吼哈嘿。
在conv_net模塊中,有五個程序文件
- layers.py: 卷積神經網絡相關的各種層次的定義,包括邏輯斯底回歸層、隱含層、卷積層、max_pooling層等
- load_data.py: 為DeepID載入數據。
- sample_optimization.py: 針對各種層次的一些測試實驗。
- deepid_class.py: DeepID主程序
- deepid_generate.py: 根據DeepID訓練好的參數,來將隱含層抽取出來
Conv_Net代碼使用
?deepid_class.py
| 12 | Usage: python deepid_class.py vec_valid vec_train params_file |
- vec_valid:?vectorize_img.py生成的
- vec_train:?vectorize_img.py生成的
- params_file: 用來存儲訓練時每次迭代的參數,可以被用來斷點續跑,由于CNN程序一般需要較長時間,萬一遇到停電啥的,就可以用得上了。自然,更大的用途是保存參數后用來抽取特征。
注意:
DeepID訓練過程有太多的參數需要調整,為了程序使用簡便,我并沒有把這些參數都使用命令行傳參。如果你想要改變迭代次數、學習速率、批大小等參數,請在程序的最后一行調用函數里改。
deepid_generate.py
可以使用下面的命令來抽取DeepID的隱含層,即160-d的那一層。
| 1 2 | Usage:pythondeepid_generate.pydataset_folderparams_fileresult_folder |
- dataset_folder: 可以是訓練集向量文件夾或者驗證集向量文件夾。
- params_file:?deepid_class.py訓練得到
- result_folder: 結果文件夾,其下的文件與dataset_folder中文件的文件名一一對應,但是結果文件夾中的向量的長度變為160而不是原來的7755。
效果展示
?DeepID 效果
跑完deepid_class.py以后,你可以得到輸出如下。輸出可以分為兩部分,第一部分是每次迭代以及每個小batch的訓練集誤差,驗證集誤差等。第二部分是一個匯總,將epoch train error valid error. 按照統一格式打印了出來。
| 123456789101112131415161718192021222324252627282930 | epoch 15, train_score 0.000444, valid_score 0.066000????????epoch 16, minibatch_index 62/63, error 0.000000epoch 16, train_score 0.000413, valid_score 0.065733????????epoch 17, minibatch_index 62/63, error 0.000000epoch 17, train_score 0.000508, valid_score 0.065333????????epoch 18, minibatch_index 62/63, error 0.000000epoch 18, train_score 0.000413, valid_score 0.070267????????epoch 19, minibatch_index 62/63, error 0.000000epoch 19, train_score 0.000413, valid_score 0.0645330 0.974349206349 0.9629333333331 0.890095238095 0.8974666666672 0.70126984127 0.6666666666673 0.392031746032 0.5201333333334 0.187619047619 0.3606666666675 0.20526984127 0.226 0.054380952381 0.1710666666677 0.0154920634921 0.1288 0.00650793650794 0.1001333333339 0.00377777777778 0.090933333333310 0.00292063492063 0.08611 0.0015873015873 0.079212 0.00133333333333 0.075466666666713 0.00111111111111 0.071466666666714 0.000761904761905 0.06815 0.000444444444444 0.06616 0.000412698412698 0.065733333333317 0.000507936507937 0.065333333333318 0.000412698412698 0.070266666666719 0.000412698412698 0.0645333333333 |
上述數據畫成折線圖如下:
向量抽取效果展示
運行deepid_generate.py之后, 可以得到輸出如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | loadingdataofvec_test/0.pkl ????buildingthemodel... ????generating... ????writingdatatodeepid_test/0.pkl loadingdataofvec_test/3.pkl ????buildingthemodel... ????generating... ????writingdatatodeepid_test/3.pkl loadingdataofvec_test/1.pkl ????buildingthemodel... ????generating... ????writingdatatodeepid_test/1.pkl loadingdataofvec_test/7.pkl ????buildingthemodel... ????generating... ????writingdatatodeepid_test/7.pkl |
程序會對向量化文件夾內的每一個文件進行抽取操作,得到對應的160-d向量化文件。
將隱含層抽取出來后,我們可以在一些其他領域上驗證該特征的有效性,比如圖像檢索。可以使用我的另一個github工程進行測試,這是鏈接.使用驗證集做查詢集,訓練集做被查詢集,來看一下檢索效果如何。
為了做對比,本文在youtube face數據上做了兩個人臉檢索實驗。
- PCA exp. 在?vectorized_img.py生成的數據上,使用PCA將特征降到160-d,然后進行人臉檢索實驗。
- DeepID exp. 在?deepid_generate.py生成的160-d數據上直接進行人臉檢索實驗。
注意:?在兩個實驗中,我都使用cosine相似度計算距離,之前做過很多實驗,cosine距離比歐式距離要好。
人臉檢索結果如下:
- 正確率如下:
| PCA | 95.20% | 96.75% | 97.22% |
| DeepID | 97.27% | 97.93% | 98.25% |
- 平均正確率如下:
| PCA | 95.20% | 84.19% | 70.66% |
| DeepID | 97.27% | 89.22% | 76.64% |
Precision意味著在top-N結果中只要出現相同類別的人,就算這次查詢成功,否則失敗。而AP則意味著,在top-N結果中需要統計與查詢圖片相同類別的圖片有多少張,然后除以N,是這次查詢的準確率,然后再求平均。
從結果中可以看到,在相同維度下,DeepID在信息的表達上還是要強于PCA的。
參考文獻
[1]. Sun Y, Wang X, Tang X. Deep learning face representation from predicting 10,000 classes[C]//Computer Vision and Pattern Recognition (CVPR), 2014 IEEE Conference on. IEEE, 2014: 1891-1898.
總結
以上是生活随笔為你收集整理的人脸验证 DeepID 算法实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Caffe实践】基于Caffe的人脸检
- 下一篇: 选择性模糊及其算法的实现。