【轉】當您聽到“以圖搜圖”時,是否首先想到了百度、Google 等搜尋引擎的以圖搜圖功能呢?事實上,您完全可以搭建一個屬於自己的以圖搜圖系統:自己建立圖片庫;自己選擇一張圖片到庫中進行搜尋,並得到與其相似的若干圖片。
Milvus 作為一款針對海量特徵向量的相似性檢索引擎,旨在助力分析日益龐大的非結構化資料,挖掘其背後蘊含的巨大價值。為了讓 Milvus 能夠應用於相似圖片檢索的場景,我們基於 Milvus 和圖片特徵提取模型 VGG 設計了一個以圖搜圖系統。
正文分為資料準備、系統概覽、 VGG 模型、API 介紹、映象構建、系統部署、介面展示七個部分。資料準備章節介紹以圖搜圖系統的資料支援情況。系統概覽章節展示系統的整體架構。VGG 模型章節介紹了 VGG 的結構、特點、塊結構以及權重引數。API 介紹章節介紹系統的五個基礎功能 API 的工作原理。映象構建章節介紹如何透過原始碼構建客戶端和伺服器端的 docker 映象。系統部署章節展示如何三步搭建系統。介面展示章節會展示系統的搜尋介面。
1。 資料準備
本文以 PASCAL VOC 圖片集為例搭建了一個以圖搜圖的端到端解決方案,該圖片集包含 17,125 張圖片,涵蓋 20 個目錄:人類;動物(鳥、貓、牛、狗、馬、羊);交通工具(飛機、腳踏車、船、公共汽車、小轎車、摩托車、火車);室內(瓶子、椅子、餐桌、盆栽植物、沙發、電視)。
資料集大小:~2GB
下載地址:http://host。robots。ox。ac。uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012。tar
說明:您也可以使用其他的圖片資料進行載入。目前支援的圖片格式有 。jpg 格式、 。png 格式。
2。 系統概覽
為了讓使用者在 web 網頁上進行互動操作,我們採取了 C/S 的架構。webclient 負責接收使用者的請求並將請求傳送給 webserver, webserver 接到 webclient 發來的 HTTP 請求之後進行運算並將運算結果返回給 webclient 。
webserver 主要由兩部分組成,圖片特徵提取模型 VGG 和向量搜尋引擎 Milvus。VGG 模型負責將圖片轉換成向量, Milvus 負責儲存向量並進行相似向量檢索。webserver 的架構如下圖所示:
3。 VGG 模型
VGGNet 由牛津大學的視覺幾何組( Visual Geometry Group )和 Google DeepMind 公司的研究員共同提出,是 ILSVRC-2014 中定位任務第一名和分類任務第二名。其突出貢獻在於證明使用很小的卷積( 3*3 ),增加網路深度可以有效提升模型的效果,而且 VGGNet 對其他資料集具有很好的泛化能力。VGG 模型在多個遷移學習任務中的表現要優於 GoogleNet ,從影象中提取 CNN 特徵, VGG 模型是首選演算法。因此,在本方案中選擇 VGG 作為深度學習模型。
VGGNet 探索了 CNN 的深度及其效能之間的關係,透過反覆堆疊 3*3 的小型卷積核和 2*2 的最大池化層, VGGNet 成功地構築了 16-19 層深的 CNN 。在本方案中使用了 Keras 的應用模組( keras。applications )提供的 VGG16 模型。
(1) VGG16 結構
VGG16 共包含 13個
卷積層
( Convolutional Layer ), 3 個
全連線層
( Fully connected Layer ), 5 個
池化層
( Pool layer )。其中,卷積層和全連線層具有權重係數,因此也被稱為權重層,總數目為 13+3=16 ,這即是 VGG16 中 16 的來源。(池化層不涉及權重,因此不屬於權重層,不被計數)。
(2) VGG16 特點
卷積層均採用相同的卷積核引數
池化層均採用相同的池化核引數
模型是由若干卷積層和池化層堆疊( stack )的方式構成,比較容易形成較深的網路結構
(3) VGG16 塊結構
VGG16 的卷積層和池化層可以劃分為不同的塊( Block ),從前到後依次編號為 Block1~Block5 。每一個塊內包含若干個卷積層和一個池化層。例如:Block2 包含 2 個卷積層( conv3-256 )和 1 個池化層( maxpool )。並且同一塊內,卷積層的通道( channel )數是相同的。
根據下圖給出的 VGG16 結構圖, VGG16 的輸入影象是 224x224x3 ,過程中通道數翻倍,由 64 依次增加到 128 ,再到 256 ,直至 512 保持不變,不再翻倍;高和寬變減半,由 224→112→56→28→14→7 。
(4) 權重引數
VGG 的結構簡單,但是所包含的權重數目卻很大,達到了 139,357,544 個引數。這些引數包括
卷積核權重
和
全連線層權重
。因此它具有很高的擬合能力。
4。 API 介紹
整個系統的 webserver 提供了 train 、process 、count、search 、delete 五個 API ,使用者可以進行圖片載入、載入進度查詢、Milvus 的向量條數查詢、圖片檢索、Milvus 表刪除。這五個 API 涵蓋了以圖搜圖系統的全部基礎功能,下面會對每個基礎功能進行介紹。
(1) train
train API 的引數如下表所示:
methodsnametypePOSTFilestring
在進行相似圖片檢索之前,需要將圖片庫載入進 Milvus,此時呼叫 train API 將圖片的路徑傳入系統。因為 Milvus 僅支援向量資料的檢索,故而需要將圖片轉化為特徵向量,轉化過程主要利用 Python 呼叫 VGG 模型來實現:
from preprocessor。vggnet import VGGNetnorm_feat = model。vgg_extract_feat(img_path)
當獲取到圖片的特徵向量之後,再將這些向量利用 Milvus 的 insert_vectors 的介面匯入 Milvus 裡面:
from indexer。index import milvus_client, insert_vectorsstatus, ids = insert_vectors(index_client, table_name, vectors)
將這些特徵向量匯入 Milvus 之後,Milvus 會給每個向量分配一個唯一的 id,為了後面檢索時方便根據特徵向量 id 查詢其對應的圖片,需要將每個特徵向量的 id 和其對應圖片的關係儲存起來:
from diskcache import Cachefor i in range(len(names)): cache[ids[i]] = names[i]
當呼叫 train API ,透過以上三步就將圖片轉成向量存入 Milvus 了。
(2) process
process API 的 methods 為 GET,呼叫時不需要傳入其他引數。process API 可以檢視圖片載入的進度,呼叫之後會看到已經載入轉化的圖片數和傳入路徑下的總圖片數。
(3) count
count API 的 methods 為 POST,呼叫時也不需要傳入其他引數。count API 可以檢視當前 Milvus 裡的向量總數,每一條向量都是由一張圖片轉化而來。
(4) search
search API 的引數如下表所示:
methodsNumfilePOSTtopk (int)image file
當你選擇好一張圖片進行相似圖片檢索時,就可以呼叫 search API。當把待搜尋的圖片傳入系統時,首先還是呼叫 VGG 模型將圖片轉化為向量:
from preprocessor。vggnet import VGGNetnorm_feat = model。vgg_extract_feat(img_path)
得到待搜尋圖片的向量之後,再呼叫 Milvus 的 search_vectors 的介面進行相似向量檢索:
from milvus import Milvus, IndexType, MetricType, Statusstatus, results = client。search_vectors(table_name=table_name, query_records=vectors, top_k=top_k, nprobe=16)
搜尋出與目標向量相似的向量 id 之後,再根據先前儲存的向量 id 和圖片名稱的對應關係檢索出對應的圖片名稱:
from diskcache import Cachedef query_name_from_ids(vids): res = [] cache = Cache(default_cache_dir) for i in vids: if i in cache: res。append(cache[i]) return res
當呼叫 search API ,透過以上三步就可以將與目標圖片相似的圖片搜尋出來了。
(5) delete
delete API 的 methods 為 POST,呼叫時不需要傳入其他引數。delete API 會刪除 Milvus 裡面的表,清空以前匯入的向量資料。
5。 映象構建
(1) 構建 pic-search-webserver 映象
首先拉取 Milvus bootcamp 的程式碼,然後利用我們提供的 Dockerfile 構建映象:
$ git clone https://github。com/milvus-io/bootcamp。git$ cd bootcamp/solutions/pic_search/webserver# 構建映象$ docker build -t pic-search-webserver 。# 檢視生成的映象$ docker images | grep pic-search-webserver
透過上述步驟就可以構建好 webserver 的 docker 映象。當然,你也可以直接使用我們上傳到 dockerhub 的映象:
$ docker pull milvusbootcamp/pic-search-webserver:0。1。0
(2) 構建 pic-search-webclient 映象
首先拉取 Milvus bootcamp 的程式碼,然後利用我們提供的 Dockerfile 構建映象:
$ git clone https://github。com/milvus-io/bootcamp。git$ cd bootcamp/solutions/pic_search/webclient# 構建映象$ docker build -t pic-search-webclient 。# 檢視生成的映象$ docker images | grep pic-search-webclient
透過上述步驟就可以構建好 webclient 的 docker 映象。當然,你也可以直接使用我們上傳到 dockerhub 的映象:
$ docker pull milvusbootcamp/pic-search-webclient:0。1。0
6。 系統部署
我們提供了 GPU 部署方案和 CPU 部署方案,使用者可以自行選擇。詳細的部署流程可以參考連結:
https://github。com/milvus-io/bootcamp/blob/0。6。0/solutions/pic_search/README。md
Step 1 啟動 Milvus Docker
詳細步驟可以參考連結:
https://milvus。io/cn/docs/v0。6。0/guides/get_started/install_milvus/install_milvus。md
Step 2 啟動 pic-search-webserver docker
$ docker run -d ——name zilliz_search_images_demo \-v IMAGE_PATH1:/tmp/pic1 \-v IMAGE_PATH2:/tmp/pic2 \-p 35000:5000 \-e “DATA_PATH=/tmp/images-data” \-e “MILVUS_HOST=192。168。1。123” \milvusbootcamp/pic-search-webserver:0。1。0
Step 3 啟動 pic-search-webclient docker
$ docker run ——name zilliz_search_images_demo_web \-d ——rm -p 8001:80 \-e API_URL=http://192。168。1。123:35000 \milvusbootcamp/pic-search-webclient:0。1。0
整個以圖搜圖系統只需三步就可以部署好了。
7。 介面展示
按照上述流程部署完成之後,在瀏覽器中輸入 “ localhost:8001 ” 就可以訪問以圖搜圖介面了。
在路徑框中填入圖片路徑進行載入,等待圖片全部轉換成向量並載入到 Milvus之後就可以進行圖片檢索了:
結語
本文利用 Milvus 和 VGG 搭建起了以圖搜圖系統,展示了 Milvus 在非結構化資料處理中的應用。Milvus 向量相似度檢索引擎可以相容各種深度學習平臺,搜尋十億向量僅毫秒響應。您可以使用 Milvus 探索更多 AI 用法!
本文轉自掘金,微信分享連結:https://mp。weixin。qq。com/s?__biz=MzUzMDI5OTA5NQ==&mid=2247484725&idx=1&sn=67027d22e433a65a253bba565a24f3aa&chksm=fa52a48dcd252d9b0b6f1038fc850178c13f3ec6db07a4dbe41518d3445c5592da5b63e4462d&token=411658804&lang=zh_CN#rd
專案主頁:https://github。com/milvus-io/milvus