最近測了一下SPTAG這個近似最近鄰搜索工具,打算拿一個東西先測測練練手,因而就想到了能夠把以前的美女圖建一個索引,看看能不能搜到想要的美女圖。前端
須要用到的環境有如下:python
代碼見:github.com/nladuo/MMFi…git
首先是準備好美女圖,這裏是我好久之前爬的一些圖,一共接近1萬張。 github
若是沒有的話,這裏提供一下Google Drive下載連接:drive.google.com/file/d/1shZ…。解壓密碼:nladuo。web
而後接下來是對圖片作一些預處理,這裏我主要打算作的並非整個的圖片搜索,整個圖片的搜索會比較麻煩。我這裏只作人臉的搜索。mongodb
這裏經過face_recognition
這個庫,把只有一張人臉的圖片保存下來,並提取人臉,而後放到mongodb裏面。docker
cd MMFinder/data_preprocess
python3 filter_images.py
複製代碼
這裏過濾出來9477
張圖片 數據庫
接下來是要把圖片轉換成一個向量了,也就是特徵工程。由於我自己也不作圖像,因此不是很瞭解具體方法,大概查了一下,傳統的方法有SIFT
,如今的話就是神經網絡
了。bash
若是是通常的圖,就用ImageNet訓練好的提取最後一層的vector做爲特徵就行了。這裏我找到了一個專門作人臉識別的一個預訓練模型:sefiks.com/2018/08/06/…,準確度應該會更高一些。網絡
模型的話就是VGG,最後一層是一個維度爲2622的向量。經過處理,這裏將全部的人臉轉換成一個2622長度的vector,而後保存到mongodb中。
cd MMFinder/data_preprocess
python3 feature_extraction.py
複製代碼
接下來是創建最近鄰的索引,也叫dense-index,在文本搜索引擎中,咱們通常用的是TF-IDF,屬於sparse-index,也就是倒排索引。而dense-index通常是圖結構的索引。
爲何要建索引呢?
其實就是加快搜索速度,若是正常狀況下,咱們搜索一張圖,其實須要和數據庫中的9477個向量都算一遍類似度,才能獲得精確的類似度排序。這個時間複雜度是O(N)的,看起來不高,可是每次搜索,都是O(N),假設有1億張圖片,那不知道要等到哪年。
有了索引以後,能夠保證搜索結果在固定的時間O(C)內返回,若是還慢,加機器就行了。
關於索引的選擇,我這裏使用的是SPTAG,由於這是一個高效可擴展的最近鄰搜索系統。相似的系統還有facebook的faiss。安裝步驟能夠見我上一篇文章:Docker下SPTAG的安裝與測試
這個安裝起來其實仍是比較麻煩的,若是想跑着玩兒,也能夠看看scikit-learn裏面的KDTree,LSH等作近似最近鄰搜索的方法。
安裝好Docker下的SPTAG以後,這裏先將全部的圖片數據導出成SPTAG規定的輸入格式。
cd MMFinder/index_construction
python3 export_SPTAG_indexbuilder_input.py
docker cp mm_index_input.txt (你的容器ID):/app/Release/
複製代碼
而後將導出的數據放到SPTAG-Docker容器裏,經過indexbuilder
創建索引。
docker attach (你的容器ID)
./indexbuilder -d 2622 -v Float -i ./mm_index_input.txt -o data/mm_index -a BKT -t 2
複製代碼
創建好索引以後,啓動搜索的rpc服務。
python3 SPTAG_rpc_search_service.py
複製代碼
接下來能夠進入查詢測試了,若是是mac用戶能夠安裝imgcat
工具,在命令行就能查看圖片。
python3 search_test.py
複製代碼
效果以下,感受仍是能夠的
最後是把各個模塊整合一下,編寫上傳,搜索接口,造成一個完整的應用的Demo。
cd web_demo
python3 main.py
複製代碼
效果以下: