以图搜图在生活中有着广泛的应用, 当我们在电视上看到有人穿着一件美丽的裙子或者帅气的球鞋也想拥有时, 我们可以拍张照片然后打开淘宝然后上传照片就可以快速的找到这个商品. 我们看到一张电影截图想知道出处的时候只要将图片粘贴到百度或者谷歌的图搜框中就可以找到相关电影的信息. 以图搜图还可以通过照片在海量的人物相册中快速的找到想要找的目标. 当您在使用百度谷歌等搜索引擎的以图搜图功能的时候的时候是否觉得这种"黑科技"遥不可及呢?
其实通过AnalyticDB提供的深度学习算法和高效向量检索, 我们只需要使用SQL就可以轻松的搭建一套以图搜图系统, 不需要掌握tensorflow, pytorch等深度学习框架, 也不需要学习OpenCV之类的视觉算法库. 本文将介绍如何通过AnalyticDB来快速搭建一套以图搜图系统. 内容包括: 以图搜图原理介绍, AnalyticDB以图搜图演示, 以图搜图代码实现, AnalyticDB的产品介绍, 总结和演示系统的源码分享.
以图搜图又被称为反向图搜(Reverse image search)是一种基于内容的图像检索(Content-based Image Retrieval) 技术. 以图片作为查询的对象, 以图搜图系统会在大量的图像记录中返回与查询图像内容最相关的记录. 例如, 商品图搜会返回与查询图片中主体物品相同或相似的图片信息. 人脸的图搜会根据图片中人脸特征返回目标人物的记录. 如下图所示是一个以图搜图的流程图. 以图搜图应用的核心模块有两个, 其中特征提取模块主要负责从图像中提取视觉特征, 从而获得一个高维的特征向量, 在这个高维特征空间中越相似的图像距离越近. 向量检索模块负责在海量的图像特征向量集中查找与查询图片特征最接近的前k个记录, 并返回.
当前主流的特征提取算法主要使用深度学习模型里如VGG[1], ResNet[2] , MobileNet[3], SqueezeNet[4]等模型作为主干网络, 然后使用不同的方法生成特征. 最简单的方法是直接将分类模型例如VGG模型的分类层前一层输出作为图像的特征. 这种算法在以图搜图场景中往往召回率不是很高. 第二种方法是将模型的中间层的特征经过特殊的的方法池化如RMAC[5], GeM[6] 和降维从而得到. 第三种方法是将模型在目标数据集上使用专门设计的损失函数进行前一训练. 例如商品以图搜图特征提取模型通常需要在商品数据集上进行迁移学习, 才能更加准确的提取不同商品的视觉特征。
AnalyticDB提供的通用以图搜图模型采用了阿里云自研的特征提取模型.AnalyticDB模型使用海量图片训练并且使用了先进的特征后处理方法. 与常用的VGG分类模型特征提取模型相比, AnalyticDB利用了多个尺度的特征,更好的平衡图像的局部特征和高层次特征, 在多样的图像场景中有更好的泛化能力。
AnalyticDB还提供了阿里云自研的人脸特识别模型, 基于大量数据训练, 模型已经在多个城市的安防和新零售场景大规模使用. 在百万人脸ID的相册中千分之一误识率下召回率可以达到99%.
向量检索又称为最近邻( Nearest Neighbor Search, NN)检索, 主要负责在海量特征向量中快速的查找与查询向量距离最近的k个记录, 虽然暴力的计算查询向量与数据库中所有向量的距离然后再进行排序可以找到最相近的记录, 但是这种方法的时间复杂度在大规模数据场景下无法满足需求的. 在实际应用场景中, 通常使用近似最近邻检索(Approximate Nearest Neighbor, ANN)的方法, ANN主要是利用向量数据分布的特性以牺牲一定检索精度为代价,快速的返回可能是查询目标最近邻的记录. 常见的ANN的方法有基于局部敏感哈希(LSH)的方法[7], 基于乘积量化的方法[8]和基于图的方法[9].
OpenAnalytic是AnalyticDB上的非结构化分析工具, OpenAnalytic 提供了丰富的图像, 视频, 文本分析的AI算法算子, 如人脸检测, 人脸识别, 人脸性别,年龄识别, 商品属性识别, 图像目标检测, 声纹识别, 文本特征提取等. 用户可以根据实际需求来任意的使用这些AI算子来自由的编排自己的算法pipeline. 例如, 本问中使用的图像特征提取pipeline和人脸特征提取pipeline如下图所示. 用户只需要通过pipeline_create UDF创建pipeline, 就可以在AnalyticDB集群上分布式的运行这些已创建的pipeline获取非结构化数据分析的结果.
我们使用AnalytcDB搭建了两套演示系统, 一套是通用的以图搜图的系统另一套是人脸检索系统. 演示系统的源码已经全部开源, 只需要下载源码(代码地址见章节6)并开通AnalyticDB就可以一键启动演示系统. 为了方便用户体验, AnalyticDB推出了1元购活动, 只需1元就可以开通. 演示的架构如下图所示, 可以看到整提架构非常简单, AnalyticDB负责图像的识别和数据的存储, 查询, 不需要依赖其他的诸如深度学习推理之类的服务.
以图搜图的演示界面如下图所示, 用户可以将本地图片批量的导入AnalyticDB作为搜索的目标相册. 用户可以通过选择本地图片或填写网络图片的URL来进行以图搜图. 同时, 用户可以选择需要返回最相似的图片数目。
我们提前向AnalyticDB中导入了近50000张图片. 如下图所示, 我们使用一张鸟类的图片进行以图搜图(右侧图片预览), 可以看到返回的全部都是相似的鸟类的照片. 每张照片下方显示了与查询图片的特征的距离, 距离越近表示越相似。
我们还可以用AnalyticDB搭建人脸检索系统, 可以通过人脸照片在相册中查询目标人物的记录.人脸检索演示的架构与以图搜图几乎相同, 差别是使用了的是人脸特征提取的算法pipeline. 我们在底库中导入了13000多张人脸照片, 然后使用人脸照片进行查询,可以看到返回结果前3张都是与查询用户是同一个人, 向量的距离都比较小, 因为我们设置了返回前10相近个结果, 但是相册中只有3张查询目标的照片, 所以返回的后7个结果与查询目标不是同一个人, 我们也可以看到这7个人与查询目标的向量距离都远远大于前3张。
下面我们来介绍如何使用AnalyticDB来实现上一章节介绍的以图搜图和人脸检索系统。
分别创建AnalyticDB的非结构化分析插件OpenAnalytic和向量检索插件fastann
CREAT EXTENSION IF NOT EXISTS open_analytic;
CREAT EXTENSION IF NOT EXISTS fastann;
我们可以使用如下sql语句建表, 表中保存了图片的名称, 二进制文件和图像的特征向量(用户也可以将图片的文件保存至阿里云的OSS对象存储服务上.这里不做详细介绍)
CREATE TABLE image_search_table (
image_name TEXT NOT NULL, # 图像文件名
image_data BYTEA NOT NULL, # 图像二进制文件
feature REAL[] NOT NULL, # 图像特征
PRIMARY KEY (image_name)
);
为图像的特征向量列构建ANN索引加快查询速度.
CREATE INDEX image_search_feature_index
ON image_search_table USING ann (feature) WITH (dim = 1024);
通过以下sql可以执行4.3创建的pipeline。 这个UDF的输入是pipeline名称和图像的byte array。 输出是包含图像特征向量的JSON串
SELECT open_analytic.pipeline_run_dist_random('general_feature_extractor',
<image_byte_array>);
通过以下sql可以执行4.3创建的pipeline. 这个UDF的输入是pipeline名称和图像的byte array. 输出是包含图像特征向量的JSON串
SELECT open_analytic.pipeline_run_dist_random('general_feature_extractor',
<image_byte_array>);
在获取图像特征以后, 可以将图像数据导入4.1创建的 image_search_table表中。
INSERT INTO image_search_table VALUES (<image_name>,
<image_byte_array>, <image_feature>);
通过以下sql可以检索与查询图片向量最相似的前10条记录。
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。