以图搜图技术演进和架构优化【优质文章】

2023-10-10 12:50

本文主要是介绍以图搜图技术演进和架构优化【优质文章】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转自:https://zhuanlan.zhihu.com/p/65306548 

高级研究员:李习华

当你看到一株未曾见过的植物,你可以打开百度APP,拍照搜索,找到相关信息;当你看到朋友穿了一件你特别喜欢的衣服,你也想买一件,你可以通过淘宝APP的拍立淘功能,找到商品;当你到达一个陌生的地方,你可以通过微信APP对着当地的街区或者建筑物拍一张照片,来定位你的详细位置。这背后都是强大的以图搜图技术。

以图搜图技术发展了许多年,从早期以图搜图的精度不尽如人意,到后来基于以图搜图技术开发出非常多的改变用户行为和提升效率的应用,经历了不小于10年的发展,整体的技术方案,数据量级,工程架构都进行了多轮的迭代。当前,各个大厂都在基于以图搜图技术来提供更好的产品,服务;我们希望在这篇文章中对以图搜图技术做一个全面的总结,主要包含以下几个方面:

1. 以图搜图技术的通用框架;

2. 以图搜图技术迭代;

3. 以图搜图是工程+算法的结合,架构演进;

Part 1. 以图搜图技术的通用框架

在这一章,我们来介绍以图搜图技术的通用框架。在介绍以图搜图技术之前,我们来看任何一个搜索技术所拥有的基本组件。举个例子,我们需要到图书馆查找一本书,需要几个基本的要素:1. 图书馆(海量图书);2. 图书的分类、书名或者作者(在图书馆的编码体系下,这些信息的组合能够唯一表示这一本书);3. 图书馆的书需要按照一定的规律来布置(科目、难易程度、首字母、作者、年份等);在有了这些基本的要素之外,只要图书馆有这本书,我们就能够快速找到它;或者即便没有某一本具体的书,我们也能够查询到这本书相近内容的书。

结合上面的例子,我们来看一个典型的以图搜图系统所拥有的基础框架:

640?wx_fmt=jpeg

先来看offline部分,包括3个基本的要素:

01. 检索图片库:这就相当于上一个例子中的图书,我们需要有一个足够规模的图片库,比如淘宝的所有商品的图片集合,比如百度图片搜索中收集到的互联网图片数据集合。当然,这里我们介绍的是一个静态的图片库,在实际项目中,我们需要有能力来处理动态变化的图片数据库;

02. 特征提取:这就相当于上一个例子中图书的作者、年份、科目等等,我们称为图片的特征。实际上,图片的任何统计量都可以作为图片的特征,甚至图像的像素值本身通过归一化之后也可以作为图片的特征。在实际中,我们使用图片的颜色分布、梯度变化统计量、纹理、BOW统计、底层/中层/高层语义特征等作为图片的特征,非常丰富。

03. 检索结构:检索结构的唯一目的就是让查找更快更准。简单的,一一对比是最简单的查询结构,最准,但是最慢;所以所有检索结构本质上都是效率和精度的平衡。常见的,我们可以对数据集进行聚类,把数据分成一堆一堆的,比对时先选择相似的堆,然后在堆内部再进行细致的比对。而分堆的理念又可以通过树结构、Hash结构、倒排索引、图结构等等来刻画。

再来看online部分,其中特征提取和offline的特征提取需要保持高度的一致性,所以实际中我们通常使用一个单独的特征服务器来提供特征提取服务。这里为什么将检索结构和检索引擎分开,主要是基于如下的考虑:检索引擎需要应对高并发等一些的工程方面的问题,所以本质上检索引擎更倾向于工程架构的优化,而检索结构更倾向于检索结构算法方面的优化;但实际上,二者是没办法完全拆分开的。

以图搜图技术本质上是寻找相似图片,但两张图片是否相似有非常多的维度:

640?wx_fmt=jpeg

因此在很多时候,以图搜图技术需要根据不同的使用场景来选择合适的技术方案,尤其是特征的选择。产品层面,也层出不穷,可以参考下面的几个链接:

The Best Image Search Engines on the Webwww.lifewire.com640?wx_fmt=jpegThe 7 Best Search Engines for Finding Free Images — SitePointwww.sitepoint.com640?wx_fmt=jpeg

Part 2. 以图搜图的技术迭代

这个部分我先打算介绍一下特征、检索引擎各自都经历了哪些迭代,然后在以不同时段典型的工业界的使用的方案来介绍以图搜图技术代际的迭代。

特征层面:

简单的,图像的单通道、多通道的颜色直方图可以作为一个简单的特征;进一步颜色矩特征,图像中任何的颜色分布都可以通过它的矩来表示。另外需要强调的局部特征是SIFT特征,参考:

https://blog.csdn.net/abcjennifer/article/details/7639681blog.csdn.net

SURF特征,HOG特征等;当有了局部特征之后,我们需要对局部特征进行聚合,作为图像的全局表示;将多个局部特征矢量聚合成一个统一维度的矢量表示的方法有:BOW、VLAD、Fisher Vector等等。深度学习技术兴起之后,基于深度学习的图像特征开始成为图像检索的主流。我们知道CNN网络具有很多不同程度对图像进行抽象的layer,较低的层得到的是图像的简单特征,而较高层得到的是图像的语义相关的特征,不同层的特征在检索层面精度有很大的区别,在Oxford Building数据集上,使用VGGNet进行简单的测试,得到了如下的统计结果,参考:

图像检索:layer选择与fine-tuning性能提升验证yongyuan.name640?wx_fmt=jpeg

640?wx_fmt=jpeg

实际上,深度网络最后的FC层同样可以作为图像的特征表示,当使用FC作为特征的时,网络训练时使用的label对检索的效果有较大的影响。理论上,label如果能够提供更多的细粒度的信息,则学习到的FC特征则更能够表达图像的细粒度特征。

特征类型对检索效果影响很大;但特征的学习方式,尤其是引入度量学习的思路之后,即便是同一个网络的同一层特征,不同的训练方式对最后的精度也会有很大的影响。

比如Class weighted conv features,参考:

https://github.com/bikong2/retrieval-2017-camgithub.com

640?wx_fmt=jpeg

分类loss和triplet loss结合:

640?wx_fmt=jpeg

引入更多监督信息的学习:

640?wx_fmt=jpeg

以及通过KL散度来优化:

640?wx_fmt=jpeg

其实通过不同的方式进行网络学习的优化方式还有很多,这里大致总结几个优化的大致方向:

1. 引入更多的监督信息;

2. 不同程度、维度的attention(包括层、channel、类等等);

3. Triplet loss及其各种变种;

4. 不同的特征聚合方式;

特征部分我们先介绍到这里,下面来介绍检索引擎。

检索引擎:

检索引擎方面,早期我们通过层次化的聚类来对数据分组,通过K-D Tree对数据进行划分,通过Hash对空间进行划分,通过倒排索引加速检索的效率,通过PQ量化对更大规模的数据进行二次方的划分。参考:

https://blog.csdn.net/qq_27245709/article/details/72393613blog.csdn.net

图像检索:基于内容的图像检索技术yongyuan.name640?wx_fmt=jpeghttps://blog.csdn.net/CHIERYU/article/details/50347735blog.csdn.net

层次化的聚类算法可以通过如下的图片来表示:

640?wx_fmt=jpeg

通过聚类来减少检索时比对的检索时间。K-D Tree和Hash请参考下面的图片。K-D Tree相对层次化聚类基本原理是一致的,不过聚类算法更多的是数据的划分,但树结构的层次化划分包含特征和数据的划分两方面。Hash方法,尤其是LSH(局部敏感哈希),则是同时在寻找特征的mapping和空间的划分。

640?wx_fmt=jpeg

PQ量化本质上是在特征和数据的两个层面对数据集进行量化,如下图所示,特征向量本身是16*8=128维,通过特征层面的划分,分成y1…y8总共8组特征;划分之后,对每一组特征在全数据集上进行聚类等量化手段,比如量化的长度是8bits的01向量。最终得到的是8*8bits的01向量,压缩比超高。

640?wx_fmt=jpeg

接下来,我们介绍两代不同的以图搜图技术。

局部特征(如SIFT特征)+BOW+LSH的方案:

这种方案大致在2015年之前算是比较流行的框架,通常针对特殊的使用场景,在检索基础上可能还需要进行细粒度的精排序。这个方案在10亿以内的数据量级上非常适用,当然如果数量级更大,也是可以的,只是需要引入其他的检索结构。关于LSH,推荐使用一个开源的工具包FALCONN:

https://github.com/FALCONN-LIB/FALCONNgithub.com

CNN卷积特征+VLAD+PQ量化的方案:

这是目前比较主流的方案,卷积特征建议做多层特征的组合,PQ量化建议根据数据规模做密集的参数选择,推荐使用Facebook开源的一个工具包FAISS:

facebookresearch/faissgithub.com640?wx_fmt=jpeg

当然,卷积特征的学习方式的选择层面,需要根据实际拥有的数据的标签信息来决策。也有一些基于弱监督学习的方案,也可以尝试。

Part 3. 以图搜图是工程+算法的结合,架构演进

在这里,我们介绍一个理想状态下的以图搜图架构,需要尝试去解决的几个问题:

1. 如何解决检索库动态增加的问题;

2. 如何解决全量的特征迭代的问题,也就是说query和database的特征需要同步;

3. 特征增强,在检索结构确定的情况下获得更好的检索效果;

4. 高并发低延迟;

640?wx_fmt=jpeg

以上只是一个简单的架构示意图,如果涉及到特征评价,检索结构评价,甚至其他的策略迭代等一些列的关于AB Test需要,架构层面需要进行深度的优化。

到这里基本上对以图搜图技术从特征、检索结构、架构等层面进行了一个基本的介绍。其实工业界的以图搜图产品或者说引擎远比我写到的要复杂,如果有大家有兴趣,建议研究一下以下几个检索系统的演进:

阿里的拍立淘

百度的图片搜索

谷歌的图片搜索

Pinterest的商品搜索

文章中参考了很多网址链接、论文,包括图片来源在此再次一并感谢,就不列出来源了;因为部分图片也是之前从论文中截图到自己的笔记当中的。感谢!

这篇关于以图搜图技术演进和架构优化【优质文章】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/180544

相关文章

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

Python多线程应用中的卡死问题优化方案指南

《Python多线程应用中的卡死问题优化方案指南》在利用Python语言开发某查询软件时,遇到了点击搜索按钮后软件卡死的问题,本文将简单分析一下出现的原因以及对应的优化方案,希望对大家有所帮助... 目录问题描述优化方案1. 网络请求优化2. 多线程架构优化3. 全局异常处理4. 配置管理优化优化效果1.

Python中高级文本模式匹配与查找技术指南

《Python中高级文本模式匹配与查找技术指南》文本处理是编程世界的永恒主题,而模式匹配则是文本处理的基石,本文将深度剖析PythonCookbook中的核心匹配技术,并结合实际工程案例展示其应用,希... 目录引言一、基础工具:字符串方法与序列匹配二、正则表达式:模式匹配的瑞士军刀2.1 re模块核心AP

MySQL中优化CPU使用的详细指南

《MySQL中优化CPU使用的详细指南》优化MySQL的CPU使用可以显著提高数据库的性能和响应时间,本文为大家整理了一些优化CPU使用的方法,大家可以根据需要进行选择... 目录一、优化查询和索引1.1 优化查询语句1.2 创建和优化索引1.3 避免全表扫描二、调整mysql配置参数2.1 调整线程数2.

深入解析Java NIO在高并发场景下的性能优化实践指南

《深入解析JavaNIO在高并发场景下的性能优化实践指南》随着互联网业务不断演进,对高并发、低延时网络服务的需求日益增长,本文将深入解析JavaNIO在高并发场景下的性能优化方法,希望对大家有所帮助... 目录简介一、技术背景与应用场景二、核心原理深入分析2.1 Selector多路复用2.2 Buffer

SpringBoot利用树形结构优化查询速度

《SpringBoot利用树形结构优化查询速度》这篇文章主要为大家详细介绍了SpringBoot利用树形结构优化查询速度,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一个真实的性能灾难传统方案为什么这么慢N+1查询灾难性能测试数据对比核心解决方案:一次查询 + O(n)算法解决

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (