DeepID实践
From:http://www.52cs.org/?p=515
DeepID實踐
作者微博:zyx_1991
小編推薦:張雨石(筆名)是北航軟院研二的童鞋,一直關注深度學習在人臉識別方面的實踐,主要研究方向也是深度學習在圖像處理上的應用,寫了多篇科普文章。本篇是 @龍星鏢局 特別邀請他寫的一篇實踐性很強的科普文章,主題是牛逼哄哄的DeepID。沒錯,就是那個識別準確率在99.15%的湯曉鷗,王小剛團隊發明的深度學習算法。另,本篇文章同步發表在作者的個人blog:http://blog.csdn.net/stdcoutzyx/article/details/45570221?,歡迎有興趣的同學長期關注。
好久沒有寫博客了,I have failed my blog. 目前人臉驗證算法可以說是DeepID最強,本文使用theano對DeepID進行實現。關于deepid的介紹,可以參見我這一片博文 DeepID之三代。
當然DeepID最強指的是DeepID和聯合貝葉斯兩個算法,本文中只實現了DeepID神經網絡,并用它作為特征提取器來應用在其他任務上。
本文所用到的代碼工程在github上:DeepID_FaceClassify,如果這篇博客幫到了你,求star??瓤?#xff0c;為了github工程的star數我覺得我太無恥了,哈哈。
實踐流程
環境配置
本工程使用theano庫,所以在實驗之前,theano環境是必須要配的,theano環境配置可以參見theano document。文檔已經較為全面,本文不再贅述,在下文中,均假設讀者已經裝好了theano。
代碼概覽
本文所用到的代碼結構如下:
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數據為例。它的文件夾結構如下所示,包含三級結構,第一是以人為單位,然后每個人有不同的視頻,每個視頻中采集出多張人臉圖像。
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的輸入圖像大小)。
Usage: python youtube_img_crop.py aligned_db_folder new_folder- aligned_db_folder: 原始文件夾
- new_folder: 結果文件夾,與原始文件夾的文件夾結構一樣,只不過圖像是被處理后的圖像。
youtube_data_split.py
用來切分數據,將數據分為訓練集和驗證集。
Usage: python youtube_data_split.py src_folder test_set_file train_set_file- src_folder: 原始文件夾,此處應該為上一步得到的新文件夾
- test_set_file: 驗證集圖片路徑集合文件
- train_set_file: 訓練集圖片路徑集合文件
test_set_file和train_set_file的格式如下,每一行分為兩部分,第一部分是圖像路徑,第二部分是圖像的類別標記。
youtube_47_55/Alan_Ball/2/aligned_detect_2.405.jpg,0 youtube_47_55/Alan_Ball/2/aligned_detect_2.844.jpg,0 youtube_47_55/Xiang_Liu/5/aligned_detect_5.1352.jpg,1 youtube_47_55/Xiang_Liu/1/aligned_detect_1.482.jpg,1vectorize_img.py
用來將圖像向量化,每張圖像都是47×55的,所以每張圖片變成一個47×55×3的向量。
為了避免超大文件的出現,本程序自動將數據切分為小文件,每個小文件中只有1000張圖片,即1000×(47×55×3)的矩陣。當然,最后一個小文件不一定是1000張。
Usage: python vectorize_img.py test_set_file train_set_file test_vector_folder train_vector_folder- test_set_file: *_data_split.py生成的
- train_set_file: *_ata_split.py生成的
- test_vector_folder: 存儲驗證集向量文件的文件夾名稱
- train_vector_folder: 存儲訓練集向量文件的文件夾名稱
Conv_Net
走完了漫漫前路,終于可以直搗黃龍了?,F在是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
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的那一層。
Usage: python deepid_generate.py dataset_folder params_file result_folder- dataset_folder: 可以是訓練集向量文件夾或者驗證集向量文件夾。
- params_file: deepid_class.py訓練得到
- result_folder: 結果文件夾,其下的文件與dataset_folder中文件的文件名一一對應,但是結果文件夾中的向量的長度變為160而不是原來的7755。
效果展示
DeepID 效果
跑完deepid_class.py以后,你可以得到輸出如下。輸出可以分為兩部分,第一部分是每次迭代以及每個小batch的訓練集誤差,驗證集誤差等。第二部分是一個匯總,將epoch train error valid error. 按照統一格式打印了出來。
epoch 15, train_score 0.000444, valid_score 0.066000epoch 16, minibatch_index 62/63, error 0.000000 epoch 16, train_score 0.000413, valid_score 0.065733epoch 17, minibatch_index 62/63, error 0.000000 epoch 17, train_score 0.000508, valid_score 0.065333epoch 18, minibatch_index 62/63, error 0.000000 epoch 18, train_score 0.000413, valid_score 0.070267epoch 19, minibatch_index 62/63, error 0.000000 epoch 19, train_score 0.000413, valid_score 0.0645330 0.974349206349 0.962933333333 1 0.890095238095 0.897466666667 2 0.70126984127 0.666666666667 3 0.392031746032 0.520133333333 4 0.187619047619 0.360666666667 5 0.20526984127 0.22 6 0.054380952381 0.171066666667 7 0.0154920634921 0.128 8 0.00650793650794 0.100133333333 9 0.00377777777778 0.0909333333333 10 0.00292063492063 0.086 11 0.0015873015873 0.0792 12 0.00133333333333 0.0754666666667 13 0.00111111111111 0.0714666666667 14 0.000761904761905 0.068 15 0.000444444444444 0.066 16 0.000412698412698 0.0657333333333 17 0.000507936507937 0.0653333333333 18 0.000412698412698 0.0702666666667 19 0.000412698412698 0.0645333333333上述數據畫成折線圖如下:
向量抽取效果展示
運行deepid_generate.py之后, 可以得到輸出如下:
loading data of vec_test/0.pklbuilding the model ...generating ...writing data to deepid_test/0.pkl loading data of vec_test/3.pklbuilding the model ...generating ...writing data to deepid_test/3.pkl loading data of vec_test/1.pklbuilding the model ...generating ...writing data to deepid_test/1.pkl loading data of vec_test/7.pklbuilding the model ...generating ...writing data to deepid_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.
總結
- 上一篇: Deep Learning – Revi
- 下一篇: Redis数据库教程——系统详解学习Re