大厂技术实现 | 图像检索及其在淘宝的应用 @计算机视觉系列
💡 作者:韩信子@ShowMeAI,Frank@淘宝
📘 大厂解决方案系列教程:https://www.showmeai.tech/tutorials/50
📘 本文地址:https://www.showmeai.tech/article-detail/92
📢 声明:版权所有,转载请联系平台与作者并注明出处
📢 收藏 ShowMeAI 查看更多精彩内容
一图读懂全文
ShowMeAI社区的技术专家小伙伴们对图像检索的典型算法做了实现,构建了相关应用 🏆『基于CNN与三元组的图像检索实现』,对细节感兴趣的话,请前往 这里 查看实现代码参考。代码的整理花费了很多心思,欢迎大家 PR 和 Star!
⭐ ShowMeAI官方GitHub:https://github.com/ShowMeAI-Hub/
图像检索是一个在互联网行业有着非常多应用场景的AI技术,典型应用例如电商商品检索(淘宝『拍立淘』,京东『拍照购』),用户随手拍照即可精准检索商品,整套实现的背后包含了非常多计算机视觉技术。本篇我们结合阿里CV方向资深算法工程师Frank的分享,一起来看看淘宝拍立淘背后的实现方案和依托的计算机视觉技术。
一、图像检索提升购物体验
图像检索任务指的是,给定一个包含特定实例(例如特定目标、建筑、场景等)的查询图像,从图像数据库中找到包含相同/相似实例的图像。
因为不同图像的拍摄视角、光照、遮挡情况等不同,完成精准检索需要很多算法技术支撑,同时对于图像数据库庞大的各大互联网公司而言,查询效率也是需要考虑的核心问题之一。
以电商为例,淘宝拍立淘于2014年首次在APP中上线,现已经成为拥有数千万日活用户的应用。与传统的基于文字搜索的电商搜索相比,拍立淘只需要用户随手拍一张照片,即可精准检索,省去了繁琐的文字描述,简化了用户的购物流程,大大提高了电商购物的体验。
二、淘宝·拍立淘的图像搜索流程架构
拍立淘的图像搜索架构如下图所示,架构整体分为离线和在线处理流程两个部分。
2.1 离线流程
离线处理的过程主要是定期对图像抽取特征构建索引。完整的离线流程包括:
1. 检测与特征学习:构建离线图像选品,通过目标检测在选品图像上提取感兴趣的商品;
2. 特征抽取:对商品进行特征提取,构建大规模索引库,放入图像搜索引擎等待查询;
3. 构建索引:以一定频率保持索引库更新。
2.2 在线流程
在线处理的过程主要是对用户上传的查询图片进行检索返回库内检索结果。具体的步骤包括:
1. 品类识别:对查询图像进行分类处理,识别商品类目;
2. 目标定位 & CNN特征抽取:提取图像目标区域的特征,基于相似性度量在索引引擎中搜索产生候选;
3. 图像索引与重排:可以通过重排序进行结果商品重排并返回搜索结果。
三、品类识别模块
3.1 图像选品处理
之所以做淘宝选品,是因为淘宝平台存在非常多相同或高度相似的商品图像,直接使用会导致最终的搜索结果出现大量相同的商品宝贝,影响用户体验。
淘宝包含大量不同来源的商品图像,例如和商品对应的『主图』、『SKU图』、『拆箱图』等。首先,需要对这些海量图像做一个筛选,选出用户相对感兴趣的图像作为商品图像构建索引。
这个过程相当于『根据图像附带的属性和图像质量等对整个图像库进行过滤』。添加图像选品过滤模块后,会每天定时选择和删除重复或高度相似的商品图像,进而优化索引文件。
3.2 基于模型&搜索结合的类目预测
淘宝的类目体系是基于叶子类目的层次化结构,这样可以兼顾视觉和语义相似性。 淘宝在拍立淘中先图像进行预测,得到14个大类目之一的结果,如服饰、鞋、包等,这个处理可以缩小图像库的搜索空间。具体实现采用基于模型与搜索结合的方式,如下:
3.2.1 基于模型的预测模块
- 采用 GoogLeNet V1 网络结构来权衡高精度和低延迟,使用包含不同商品类目标签的图像集进行训练;
- 将输入图像的大小 resize 为 256×256,随机裁剪到 227×227 ,使用 Softmax(交叉熵)损失函数作为分类任务的损失函数。
3.2.2 基于搜索的预测模块
该模块不直接训练分类模型,而是基于相似度与匹配思想,使用特征模型和待检索数据库完成基于搜索的加权KNN分类。具体的预测流程为:
- 获取用户输入的待分类图片;
- 应用基于搜索的分类方法:对图片特征提取,并在待检索的数据库中找出 Top-K 个和它相似的图片,根据这些图片的类目标签对输入图片进行预测。
3.2.3 淘宝·拍立淘应用实践
- 离线部分。淘宝收集了2亿张附带『真实类别标签』的图像作为参考图像库,训练一个通用类目的特征模型对参考图像库离线提取通用特征并构建索引。
- 在线部分。实际预测时,对查询图像提取通用特征,并在图像参考集中检索Top 30的结果。通过查询图像的Top 30个邻居,再根据每个的类目标签加权投票,以预测待查询图像的标签 。其中,加权函数为查询图像与邻居图片的距离函数。
品类识别的效果提升。 淘宝将『基于模型的预测结果』和『基于搜索的结果』再一次加权融合,以进一步提高类目预测的准确性。 相比于单方法,两者融合的方式,使得淘宝最终类目预测的精度提高了 2% 以上。
四、目标检测&特征联合学习&度量学习模块
淘宝场景下,应用拍立淘进行图像搜索,有一个大挑战:用户和商家图像之间存在巨大差异。商家的商品图片通常质量都非常高,拍摄环境和设备也非常好。而用户查询的图像,通常是用手机摄像头拍摄的,伴随着光照、模糊和复杂的背景等一系列问题。
为了减少复杂的背景影响,系统需要具备在图像中『定位主体目标』并『提取主体特征』的能力。淘宝提出了基于度量学习的分支网络CNN框架,来联合学习主体检测框和特征表示,以实现在没有背景干扰的情况下使用户实拍图像和商家的索引图像特征保持一致。
图例显示了,是否进行目标主体检测与针对性检索的效果差别:
- 第1行没有进行主体检测,检索结果明显受到了背景干扰;
- 第2行采用主体检测,检索结果有非常显著的效果提升。
4.1 三元组挖掘
4.1.1 原理简介
在度量学习中,利用三元组样本,构建『三元组损失函数(Triplet Loss Function)』是当前比较常见和有效的一种处理方式。
这个方法最早由Google研究团队在论文《 FaceNet:A Unified Embedding for Face Recognition》中提出,常用于人脸识别任务,目的是做到非同类极相似样本的区分(如对兄弟二人的区分)。
它的基本思想是:对于设定的三元组(Anchor , Positive , Negative),Triplet Loss 试图学习到一个特征空间,使得在该空间中相同类别的基准样本(Anchor)与 正样本(Positive)距离更近,不同类别的 Anchor 与负样本(Negative)距离更远。
说明:Anchor 和 Positive 为同类的不同样本;Anchor 与 Negative 为异类样本。举例:在图像检索场景下,与检索图片同样的主体内容是Positive,不一样的是Negative。
4.1.2 方法优缺点
- 优点1:基于 Triplet Loss 的神经网络模型,可以对细节进行很好地区分。 尤其是在图像分类任务中,当两个输入很相似的时候,Triplet Loss 对这两个差异性较小的输入向量,可以学习到更好的、细微的特征 Feature,从而在分类任务中表现出色。
- 优点2:相比其他分类损失函数,Triplet Loss 能够根据模型训练的需要设定一定的阈值。 带 Triplet Loss 的网络结构,在进行训练的时候一般都会设置一个阈值 margin,设计者可以通过改变 margin 的值来控制正负样本的距离。
虽然 Triplet Loss 很有效,但也有缺点:
- 缺点1:三元组的选取,导致数据的分布并不一定均匀,所以在模型训练过程表现很不稳定且收敛慢,需要根据结果不断调节参数。
- 缺点2:Triplet Loss 比分类损失更容易过拟合。
4.1.3 淘宝拍立淘应用实践
在淘宝拍立淘的场景中,给定一张输入图像,核心问题是利用图像特征可靠地匹配来自用户和卖家的不同源图像。 对应到三元组场景,我们需要拉近『查询图像』与其『同款商品图像』之间的距离,并拉远『查询图像』与『不同款商品图像』之间的距离。
这里采用的 Triplet Loss 三元组损失函数如下:
\(\operatorname{loss}\left(q, q^{+}, q^{-}\right)=\left[L 2\left(f(q), f\left(q^{+}\right)\right)-L 2\left(f(q), f\left(q^{-}\right)\right)+\delta\right]_{+}\)
- \(L2\) 表示两个向量之间的 \(L2\) 距离
- \(\delta\) 是控制间隔的参数
- \(f\) 是需要学习的 CNN 特征提取方式,可以通过端到端的训练学习到
4.1.4 三元组样本挖掘
方法思路如上,但模型训练需要依靠大量样本,这里的核心是『挖掘较难的三元组样本』。 简单的处理方式是,从与查询图像相同的类目中选择正样本图像,从其他类目中选择负样本图像。这种方式存在的问题是:负样本图像与查询图像存在较大的视觉差异,导致训练过程中三元组排序损失函数很容易为零,没有贡献任何损失。
实际上,淘宝应用『用户点击数据』来『挖掘较难的三元组样本』,具体流程如下图:
- 基本思路
在图像检索场景下,很大一部分用户会在返回列表中点击同款的商品图像,这意味着『点击的图像』可以被视为『查询图像的正样本图像』,『未点击图像』可以作为『难负样本图像』,它们类似于查询图像但属于非同款商品图像。
- 问题点&解决方式
上述的思路中,『未点击的图像』仍然可能是『与查询图像具有同款商品的图像』,因为当许多同款的宝贝图像被返回时,用户只会点击结果中的一个或两个,我们需要过滤『未点击且与查询图像具有同款商品的图像』。
- 负样本构建
最终『查询图像的负样本图像』计算如下:
\(q^{-} \in\left\{d^{\text {nonclick }} \mid \min \left[\operatorname{dist}\left(d^{\text {nonclick }}, q\right), \operatorname{dist}\left(d^{\text {nonclick }}, d^{\text {click }}\right)\right] \geqslant \gamma\right\}\)
- \(dist\) 为特征的距离函数
- \(\gamma\) 为距离阈值
淘宝拍立淘对距离计算做了一些设计,采用了多特征融合的方法,结合了『局部特征』、『不同版本特征』和『ImageNet预训练的通用特征』等,从而更准确地发现噪声负样本。
- 正样本构建
类似的思路,更精确的『查询图片正样本』选取方式如下公式所示:
\(q^{+} \in\left\{d^{\text {click }} \mid \operatorname{dist}\left(d^{\text {click }}, q\right) \leqslant \varepsilon\right\}\)
- 数据扩增
拍立淘的样本构建时,在小批量中获取的三元组之间,共享所有负样本图像。这样可以扩展小批量中的所有可用三元组数据,增加更多训练数据。不采用共享机制,生成 \(m\) 个三元组,通过共享负样本,可以在进入损失层之前生成m平方个三元组。
- 损失函数优化
为进一步减少训练图像中的噪声,对原始三元组排序损失函数进行改进:
改进的思路,是针对同一查询图像的所有三元组样本计算平均损失,这样可以最大程度地减少噪声三元组的影响。 通过查询图像层面的三元组损失函数,学习CNN 特征,从而将用户的实拍图像和商家的高质量图像映射到同一特征空间,使得不同来源的图像能够更可靠地匹配。
Triplet Loss 的简单代码实现示例
class TripletLoss(nn.Module):
"""
pytorch上的Triplet Loss实现
"""
def __init__(self, margin):
super(TripletLoss, self).__init__()
self.margin = margin
def forward(self, anchor, positive, negative, size_average=True):
distance_positive = (anchor - positive).pow(2).sum(1) # .pow(.5)
distance_negative = (anchor - negative).pow(2).sum(1) # .pow(.5)
losses = F.relu(distance_positive - distance_negative + self.margin)
return losses.mean() if size_average else losses.sum()
4.2 Deep Ranking 网络
4.2.1 网络结构
整个流程中重要的一个环节是『剔除背景噪声,检测出主体对象』。计算机视觉中,目标检测的方法是部署现成的主体检测算法(如 Faster R-CNN 或 SSD),但这类方法时延较长而且需要大量边界框的标注。
淘宝拍立淘提出『两个分支的联合网络模型』,来同时学习检测和特征表示。分支网络模型结构如下图所示:
4.2.2 参数学习与训练
以上个步骤中挖掘的三元组为监督信息,在Deep Ranking 框架下学习该联合模型。这种方式下,可以通过三元组正负样本度量关系来学习出判别特征,同时,根据分支结构回归出对特征判别起到重要作用的对象主体掩膜。在不需要边界框标注的情况下,主体掩膜通过分支结构以类似注意力的机制被学习出来。 总体来说,Deep Ranking 框架如下图所示。
Deep Ranking 框架下的每个深度联合模型都共享参数,检测的掩膜函数 \(M(x , y)\) 如下公式所示,先利用检测分支回归出矩形坐标 \((x_{1} , x_{r}, y_{t} , y_{b})\),再使用阶跃函数 \(h\) 表示:
主体边界框区域是输入图像 \(I(x,y)\) 与 \(M(x,y)\) 按位点乘得到的。然而,阶跃函数 \(h\) 是不可微的。为了端到端地训练,我们可以用 \(Sigmoid\) 函数来逼近阶跃函数。
\(f(x)=\frac{1}{1+\mathrm{e}^{-k x}}\)
当 \(K\) 足够大时使其可微化。 整个过程只需要弱监督的用户点击数据,不需要依赖边界框的标注进行训练,这大大降低了人力资源成本,提高了训练效率。
五、图像索引与重排模块(Image Indexing & Re-ranking)
5.1 十亿级大规模图像检索引擎
实际引擎端为了最大程度加快响应速度,淘宝拍立淘使用大规模二值引擎进行查询和排序,整体采用 Multi-shards 和 Multi-replications 引擎架构。
5.1.1 结构框架
结构如下图所示,它保证了大量用户查询下的快速响应,同时又具有非常好的可扩展性。
- Multi-shards
单机内存无法存储庞大的特征数据,因此特征被存储到多个节点上。每次查询,将从每个节点检索出 Top-K 结果,将其合并得到最终的结果。
- Multi-replications
单个特征数据库无法应对大量的查询流量,特征数据库被复制多份,从而将查询流量分流至不同的服务器集群上,以降低用户的平均查询时间。
5.1.2 粗筛选和精排序
在每个节点,使用两种类型的索引:粗筛选和精排序,解释如下:
粗筛选:采用改进的基于二值特征(CNN 特征二值化)的二值倒排索引检索。
- 以图像ID为关键字、二值特征为值,通过汉明距离计算,快速滤除大量不匹配数据。
- 根据返回的图像数据的二进制编码,对最近邻进行精排序。
精排序:根据附加元数据(如视觉属性和特征)对粗筛选出的候选项进行更精确的排序。精排过程较慢:
- 元数据以非二进制形式存储
- 元数据的存储开销太大,无法将其全部载入内存中。这里缓存命中率是影响性能的关键因素。
通过粗筛选和精排序(这个过程和推荐系统中的召回+排序非常类似),基本可以满足达到无损精度的召回结果,且检索效率大幅提升。
5.2 结合多信息维度的结果重排
5.2.1 存在的问题
上面的图像检索结果,基于计算机视觉与深度学习排序,尽量精准地检索回图片商品。但回归到电商的本质,同款商品可能有很多不同的配图。匹配最接近检索图片形态的同款商品结果,并不能保证它们是最能激发用户点击和购买的商品。
5.2.2 淘宝·拍立淘的解决方案
业务目标调整变更之后,变成了1个综合排序问题,最后要根据结果列表里的商品的价格、好评度、销量、用户画像等综合信息重排序。 经过上述图像检索的过程,淘宝拍立淘得到的初步结果列表包含 Top 60 图像相似度的同款结果,进一步利用语义信息对 Top 60 的结果进行重新排序,包括使用销量、转化率、点击率、用户画像等。
- 简单的处理方式可以是利用 GBDT+LR 这种传统模型,对不同维度的相关描述特征进行集成,将最终得分归一化到0,1,以保证外观相似度的同时,综合考虑其他属性维度的重要性。
- 更精准的排序方式,可以考虑 CTR 预估模型与多目标优化的复杂网络方法,参考『多目标排序』 『爱奇艺多目标』等过往文章。结合多信息维度的结果重排序阶段,使得最终结果在保持整体外观相似性的同时,对质量差的图像进行降权与过滤,获得更符合用户意图的商品图像。
参考文献
[1] Shaoqing Ren, Kaiming He, Ross B Girshick,et al. Faster R-CNN: Towards Real-Time Object Detection with Region ProposalNetworks. IEEE Transactions on Pattern Analysis and MachineIntelligence(T-PAMI), 2017:1137–1149.
[2] Wei Liu, Dragomir Anguelov, Dumitru Erhan,et al. SSD: Single Shot MultiBox Detector. In European Conference on ComputerVision (ECCV), 2016:21–37.
[3] YanhaoZhang, Pan Pan, Yun Zheng,et al. Visual Search at Alibaba. In Proceedings of the 24th InternationalConference on Knowledge Discovery and Data Mining (SIGKDD), 2018:993-1001
[4] Yushi Jing, David C Liu, Dmitry Kislyuk,et al. Visual Search at Pinterest. In Proceedings of the 21th InternationalConference on Knowledge Discovery and Data Mining (SIGKDD), 2015:1889–1898
[5] Christian Szegedy, Wei Liu, Yangqing Jia,et al. Going deeper with convolutions. In IEEE Conference on Computer Visionand Pattern Recognition(CVPR), 2015:1–9.
[6] Jiang Wang, Yang Song, Thomas Leung, etal. Learning Fine-Grained Image Similarity with Deep Ranking. In IEEEConference on Computer Vision and Pattern Recognition(CVPR), 2014:1386–1393.
[7] OlgaRussakovsky, Jia Deng, Hao Su, et al. ImageNet Large Scale VisualRecognition Challenge. (2014). arXiv:arXiv:1409.0575, 2014.
ShowMeAI 大厂技术实现方案推荐
- 大厂解决方案系列 | 数据集&代码集(持续更新中):https://www.showmeai.tech/tutorials/50
- ShowMeAI官方GitHub(实现代码):https://github.com/ShowMeAI-Hub/
- 『推荐与广告』大厂解决方案
- 『计算机视觉 CV』大厂解决方案
- 『自然语言处理 NLP』大厂解决方案
- 『金融科技』大厂解决方案
- 『生物医疗』大厂解决方案
- 『智能制造』大厂解决方案
- 『其他AI垂直领域』大厂解决方案