Milvus實戰 | 輕鬆搭建以圖搜圖系統

當您聽到「以圖搜圖」時,是否首先想到了百度、Google 等搜索引擎的以圖搜圖功能呢?事實上,您徹底能夠搭建一個屬於本身的以圖搜圖系統:本身創建圖片庫;本身選擇一張圖片到庫中進行搜索,並獲得與其類似的若干圖片。git

Milvus 做爲一款針對海量特徵向量的類似性檢索引擎,旨在助力分析日益龐大的非結構化數據,挖掘其背後蘊含的巨大價值。爲了讓 Milvus 可以應用於類似圖片檢索的場景,咱們基於 Milvus 和圖片特徵提取模型 VGG 設計了一個以圖搜圖系統。github

正文分爲數據準備、系統概覽、 VGG 模型、API 介紹、鏡像構建、系統部署、界面展現七個部分。數據準備章節介紹以圖搜圖系統的數據支持狀況。系統概覽章節展現系統的總體架構。VGG 模型章節介紹了 VGG 的結構、特色、塊結構以及權重參數。API 介紹章節介紹系統的五個基礎功能 API 的工做原理。鏡像構建章節介紹如何經過源代碼構建客戶端和服務器端的 docker 鏡像。系統部署章節展現如何三步搭建系統。界面展現章節會展現系統的搜索界面。web

 

1. 數據準備

本文以 PASCAL VOC 圖片集爲例搭建了一個以圖搜圖的端到端解決方案,該圖片集包含 17,125 張圖片,涵蓋 20 個目錄:人類;動物(鳥、貓、牛、狗、馬、羊);交通工具(飛機、自行車、船、公共汽車、小轎車、摩托車、火車);室內(瓶子、椅子、餐桌、盆栽植物、沙發、電視)。算法

數據集大小:~2GBdocker

下載地址: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 做爲深度學習模型。app

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 的參數以下表所示:

methods name type
POST File string

在進行類似圖片檢索以前,須要將圖片庫加載進 Milvus,此時調用 train API 將圖片的路徑傳入系統。由於 Milvus 僅支持向量數據的檢索,故而須要將圖片轉化爲特徵向量,轉化過程主要利用 Python 調用 VGG 模型來實現:

from preprocessor.vggnet import VGGNet
norm_feat = model.vgg_extract_feat(img_path)

當獲取到圖片的特徵向量以後,再將這些向量利用 Milvus 的 insert_vectors 的接口導入 Milvus 裏面:

from indexer.index import milvus_client, insert_vectors
status, ids = insert_vectors(index_client, table_name, vectors)

將這些特徵向量導入 Milvus 以後,Milvus 會給每一個向量分配一個惟一的 id,爲了後面檢索時方便根據特徵向量 id 查找其對應的圖片,須要將每一個特徵向量的 id 和其對應圖片的關係保存起來:

from diskcache import Cache
for 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 的參數以下表所示:

methods Num file
POST topk (int) image file

當你選擇好一張圖片進行類似圖片檢索時,就能夠調用 search API。當把待搜索的圖片傳入系統時,首先仍是調用 VGG 模型將圖片轉化爲向量:

from preprocessor.vggnet import VGGNet
norm_feat = model.vgg_extract_feat(img_path)

獲得待搜索圖片的向量以後,再調用 Milvus 的 search_vectors 的接口進行類似向量檢索:

from milvus import Milvus, IndexType, MetricType, Status
status, results = client.search_vectors(table_name=table_name, query_records=vectors, top_k=top_k, nprobe=16)

搜索出與目標向量類似的向量 id 以後,再根據先前存儲的向量 id 和圖片名稱的對應關係檢索出對應的圖片名稱:

from diskcache import Cache
def 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 用法!

更多關於VGG模型的信息請瀏覽:

VGG 官方網站:

http://www.robots.ox.ac.uk/~vgg/research/very_deep/

VGG Github:

https://github.com/machrisaa/tensorflow-vgg

 

| 歡迎加入 Milvus 社區

milvusio.slack.com | Slack 社區

zhihu.com/org/zilliz-11/columns | 知乎

zilliz.blog.csdn.net | CSDN 博客

相關文章
相關標籤/搜索