作者 | 小龙

责编 | 胡巍巍

当您听到“以图搜图”时,是否首先想到了百度、Google 等搜索引擎的以图搜图功能呢?事实上,您完全可以搭建一个属于自己的以图搜图系统:自己建立图片库;自己选择一张图片到库中进行搜索,并得到与其相似的若干图片。

Milvus 作为一款针对海量特征向量的相似性检索引擎,旨在助力分析日益庞大的非结构化数据,挖掘其背后蕴含的巨大价值。为了让 Milvus 能够应用于相似图片检索的场景,我们基于 Milvus 和图片特征提取模型 VGG 设计了一个以图搜图系统。

正文分为数据准备、系统概览、 VGG 模型、API 介绍、镜像构建、系统部署、界面展示七个部分。数据准备章节介绍以图搜图系统的数据支持情况。系统概览章节展示系统的整体架构。VGG 模型章节介绍了 VGG 的结构、特点、块结构以及权重参数。API 介绍章节介绍系统的五个基础功能 API 的工作原理。镜像构建章节介绍如何通过源代码构建客户端和服务器端的 Docker 镜像。系统部署章节展示如何三步搭建系统。界面展示章节会展示系统的搜索界面。

数据准备

本文以 PASCAL VOC 图片集为例搭建了一个以图搜图的端到端解决方案,该图片集包含 17,125 张图片,涵盖 20 个目录:人类;动物(鸟、猫、牛、狗、马、羊);交通工具(飞机、自行车、船、公共汽车、小轿车、摩托车、火车);室内(瓶子、椅子、餐桌、盆栽植物、沙发、电视)。

数据集大小:约2GB

下载地址:

http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar

说明:您也可以使用其他的图片数据进行加载。目前支持的图片格式有JPG格式、PNG格式。

系统概览

为了让用户在 Web 网页上进行交互操作,我们采取了 C/S 的架构。webclient 负责接收用户的请求并将请求发送给 webserver, webserver 接到 webclient 发来的 HTTP 请求之后进行运算并将运算结果返回给 webclient 。

webserver 主要由两部分组成,图片特征提取模型 VGG 和向量搜索引擎 Milvus。VGG 模型负责将图片转换成向量,Milvus 负责存储向量并进行相似向量检索。webserver 的架构如下图所示:

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 个参数。这些参数包括卷积核权重和全连接层权重。因此它具有很高的拟合能力。

API 介绍

整个系统的 webserver 提供了 train 、process 、count、search 、delete 五个 API ,用户可以进行图片加载、加载进度查询、Milvus 的向量条数查询、图片检索、Milvus 表删除。这五个 API 涵盖了以图搜图系统的全部基础功能,下面会对每个基础功能进行介绍。

(1) Train

train API 的参数如下表所示:

在进行相似图片检索之前,需要将图片库加载进 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 的参数如下表所示:

当你选择好一张图片进行相似图片检索时,就可以调用 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 里面的表,清空以前导入的向量数据。

镜像构建

(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

系统部署

我们提供了 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

整个以图搜图系统只需三步就可以部署好了。

界面展示

按照上述流程部署完成之后,在浏览器中输入 " localhost:8001 " 就可以访问以图搜图界面了。

在路径框中填入图片路径进行加载,等待图片全部转换成向量并加载到 Milvus之后就可以进行图片检索了:

结语

本文利用 Milvus 和 VGG 搭建起了以图搜图系统,展示了 Milvus 在非结构化数据处理中的应用Milvus 向量相似度检索引擎可以兼容各种深度学习平台,搜索十亿向量仅毫秒响应。

【End】

推荐阅读 

☞有想法!这群程序员试图用退役挖矿机协助消灭新冠状病毒

☞Yann LeCun 会成为下一个居里夫人吗?

☞破解面试难题8个角度带你解读SQL面试技巧!

我就不信 35 岁做不了程序员!

☞在非托管钱包中可能会出现价值3000万美元的BCH SIM 交换黑客攻击吗?

☞对标Pytorch,清华团队推出自研AI框架“计图”

你点的每一个在看,我认真当成了喜欢

7 招教你轻松搭建以图搜图系统!相关推荐

  1. Torch、Java、Milvus快速搭建以图搜图系统

    Torch.Java.Milvus快速搭建以图搜图系统 1 原理概述 以图搜图大致原理(口水话版) 以图搜图,即通过一张图片去匹配数据库中的图片,找到最相似的N张图.在我们普通的搜索系统中,文字匹配的 ...

  2. 使用AnalyticDB轻松实现以图搜图和人脸检索

    1. 背景 以图搜图在生活中有着广泛的应用, 当我们在电视上看到有人穿着一件美丽的裙子或者帅气的球鞋也想拥有时, 我们可以拍张照片然后打开淘宝然后上传照片就可以快速的找到这个商品. 我们看到一张电影截 ...

  3. 无法检索数据和目标数据的列信息_使用AnalyticDB轻松实现以图搜图和人脸检索...

    1. 背景 以图搜图在生活中有着广泛的应用, 当我们在电视上看到有人穿着一件美丽的裙子或者帅气的球鞋也想拥有时, 我们可以拍张照片然后打开淘宝然后上传照片就可以快速的找到这个商品. 我们看到一张电影截 ...

  4. 搭建自己的以图搜图系统(二):深入优化搭建生产级别的图搜系统

    概述 本文是"搭建自己的以图搜图系统"系列的第二篇,在第一篇内容中我们了解了如何利用"机器学习框架 Towhee ¹"和"向量数据库 Milvus ² ...

  5. 推荐系统工程篇之搭建以图搜图服务

    基于内容的召回在推荐系统中是比较常见的召回策略,常见有基于用户或物品的标签召回或者基于用户的年龄,地域等召回,一般该策略的实现是基于开源软件 Elasticseach 实现的.虽然召回的结果都比较合理 ...

  6. 工程篇之搭建以图搜图服务

    基于内容的召回在推荐系统中是比较常见的召回策略,常见有基于用户或物品的标签召回或者基于用户的年龄,地域等召回,一般该策略的实现是基于开源软件 Elasticseach 实现的.虽然召回的结果都比较合理 ...

  7. 使用Milvus搭建以图搜图服务

    使用Milvus搭建以图搜图服务 介绍 安装Milvus Java调用Milvus插入.查询 引入Maven依赖 创建Milvus客户端 实现Milvus插入向量数据 实现Milvus 查询向量 结尾 ...

  8. 基于 Milvus 的以图搜图系统 2.0

    Milvus 以图搜图 1.0 版本自发布以来便受到广大用户的欢迎.近日,Zilliz 推出了 Milvus 以图搜图系统 2.0 版.本文将介绍 Milvus 以图搜图系统 2.0 版的主要更新内容 ...

  9. python+milvus实现一个以图搜图系统

    目录 引言 说明 准备数据 训练数据 安装minlvus(docker-compose方式) python集成milvus+towhee python后端启动方式 启动前端 查询数据 引言 当您听到& ...

最新文章

  1. 【Java学习】多线程2
  2. how to become a very good candidate at the investment bank?
  3. mysql主从复制缺陷_mysql主从复制及遇到的坑
  4. 包r语言_R语言入门之寻找你的R包
  5. java地址传递_关于java中是地址传递还是值传递的测试
  6. 负margin在布局中的运用(*****************************************************************)...
  7. NVIDIA Parallel Nsight
  8. php 队列 api,GitHub - shirakun/think-queue: ThinkPHP 队列支持
  9. HVM is required for this operation - Run Xen on Nested System
  10. solr5.3.1 mysql_Solr-5.3.1 dataimport 导入mysql数据
  11. Quart2D文字图像绘制
  12. 【学习笔记】matlab进行数字信号处理(三)数字滤波技术
  13. R语言--Cox模型校准曲线原理(二)算法
  14. 【论文阅读】Multi-Modal Sarcasm Detection Based on Contrastive Attention Mechanism
  15. 怎么给HTML文件加背景,设置文件夹背景,如何设置文件夹背景颜色
  16. 3D Local Features for Direct Pairwise Registration论文阅读
  17. 31、Flutter之Hero动画
  18. ARM主板跑java_在ARM Cortex-M3上编写一个简单的C任意代码执行漏洞?
  19. vue-element-admin 和 python django 前后端分离 开撸(新手学习,高手指点)
  20. 【毕业季-进击的技术er】:即将大四在校生的技术分享,未来共勉

热门文章

  1. 后代选择+++margin-right:auto
  2. BigDecimal与double
  3. Robot Framework中经常用的第三方库的安装方法
  4. iOS的四种持久化存储
  5. Windows Thrift安装及HelloWorld
  6. 从头来之【iOS及历史版本特性介绍】
  7. 自然语言处理(2)之文本资料库
  8. 【转】MongoDB资料汇总专题
  9. 修改JSONArray里所有key的值
  10. [VSCode] 设置 pylint 以解决 Module ‘torch‘ has no ‘xxx‘ member