標籤:卷積神經網路 deepid
DeepID實踐
轉載請註明: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。咳咳,為了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,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張。
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
走完了漫漫前路,終於可以直搗黃龍了。現在是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.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之後, 可以得到輸出如下:
loading data of vec_test/0.pkl building the model ... generating ... writing data to deepid_test/0.pklloading data of vec_test/3.pkl building the model ... generating ... writing data to deepid_test/3.pklloading data of vec_test/1.pkl building the model ... generating ... writing data to deepid_test/1.pklloading data of vec_test/7.pkl building 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距離比歐式距離要好。
人臉檢索結果如下:
| Precision |
Top-1 |
Top-5 |
Top-10 |
| PCA |
95.20% |
96.75% |
97.22% |
| DeepID |
97.27% |
97.93% |
98.25% |
| AP |
Top-1 |
Top-5 |
Top-10 |
| 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演算法實踐