原创:王稳钺
资料来源:Mozak
一、如何从淘宝找同款
电商本身就是用户体量非常多的业务场景,也是产生利润最多的一个业务场景。我们如何从淘宝找到同款商品呢?
image
一种情况是,在 PC 端,在商品的列表的页面,可以把鼠标放在商品图片上面,然后就会显示找同款。点击找同款,就会找到相似商品。从图中可以看到第一个和第三个商品和原商品很相似,但是第二个商品和原始商品一点都不相似,而且标题都不相似。所以说就算淘宝在做找同款这一技术,这个场景下面也做得并不是 100% 完美。所以说找同款技术在电商领域是还是有非常大的应用场景和发展空间的。对于消费者而言,可以利用找相似来找到相同款式下,价格最低的商品。
如果是想从自己的图片,去找同款商品,这又是一个不一样的技术。这种情况和上述直接找同款差别非常大的。这种情况一般叫做“拍照过”,也就是说用户自己去拍摄一个商品,然后再去找到同款。其实和上一种情况是不同的业务场景。所以说在做具体的建模的时候,这两类任务其实是需要区分对待的。而这第二类任务其实是非常难的,因为用户拍摄的具体情况是千变万化的,角度问题、光线暗、有褶皱都是非常常见的。
二、如何找到相似款式
通过淘宝的两个案例,可以看到淘宝是怎么做到找同款的,那么它的大致的实现的原理是什么呢?在我们进行检索商品的时候,有两类检索方法,第一类是文本的检索,第二类是基于内容的检索。基于文本的检索就是通过具体的TXT ,或者 keyword 来检索,比如红米 p20 、华为 p40 。这是用一个文本去描述我们的商品。那么对于服饰而言,可以利用它是一个抹肩裙,它的主要颜色,材质,中码的还是小码等来描述,这些keyword 一般会出现在商品的标题里,商家经常通过堆叠关键词来匹配用户的检索结果。基于文本的检索其实是非常常规的,这种情况一般的搜索引擎都可以做到,比如百度、必印等,其实他们都是基于文本构建搜索引擎的。
第二类就是基于内容的检索。基于内容检索是指在具体的建模的过程中,并不是基于文本信息,而是基于图片的内容进行检索。因为有些时候是很难去描述一个图片的。假如一个不是时装行业内的人或者说对时尚并不太了解的人,去描述一个裙子,是很难用很准确的文本信息去描述的。如果用户的描述和店家的描述不同,通过文本就是检索不到的。同一件商品或者同一个图片,人们通常会从不同的角度去形容它。果想要解决这种说文本检索的缺点,就要用到基于内容检索。
基于内容检索就是尝试用图片上的一个内容,它原始的一些像素去构建一个检索的向量,然后去计算相似度。一个图片其实它包含的一个数据维度是非常高的。常见的图片可能是 500 乘 500 的像素,如果算上 RGB 算通道的话,那么它就是一个由几十万数值所组成的一个矩阵。那么对于一个图片而言,如何去提取它的有效的特征就成为了关键。很多时候肉眼可以判断两张图片是相似的,但是很难进行描述。所以如何描述图片和计算相似度等都是基于内容检索需要解决的问题。
首先第一部分,如何描述图片其实在一些计算机视觉和深度学习的一些基础知识中会讲到,可以尝试提取图片的颜色的直方图,或者提取图片的整体的特征,甚至可以提取在深度学习中的一些卷积特征。所以说这一部分需要具备一些计算机视觉、数字图像处理和深度学习的知识。第二部分,如何计算相似度呢?这一部分可能会有更多的问题。在进行相似度计算的时候,假如有四张图片,想要看图片 A 和图片 B、C、D 是不是相似的,可以A与B,A与 C,A 与 D 一个一个比较,这个其实是很天然的一种想法。但是一个个比较,随着商品数量越来越多,比较的次数也会越来越多,就会需要大量的时间。所以如何计算相似度和计算的加速问题都是需要解决的。
三、如何计算图像相似度
如何计算相似度呢,这一部分会用具体的代码展示。
image
首先使用的是淘宝的数据集,数据集中包括商品的标题,商品的图片,商品的型号。
image
通过Pandas读取数据集。第0列是商品的编号。第1列是商品的标题,这是它原始的中文文本。第2列、第3列是商品的主图,也就是商品的图片。数据集为了防止图片过期,所以给了两个地址,两个地址其实是一样的,只需要用其中一列就可以。最后一列是商品具体的款式描述,而这一列是人为标注的。
image
接下来需要对数据集进行处理,因为数据集提供的是原始的链接,需要获取一下本地的链接,然后将获取的路径做一个转化。在原始的数据集里面,可能有一些图片缺失了,无法下载,或者数据集中有一些噪音图片,所以要进行清洗。可以做一个简单的判断,如果具体的一个图片在我们的路径下存在的话,就保留;如果不存在,则剔除。
image
通过数据的可视化可以看到前五个商品都是玻尿酸爽肤水。它们的图片都很相似,但是也存在有一些区别。第二张图片,第三张图片是没有背景的,而其他的是有背景的。第四张、第五张图片是有文字的,而其它图片是没有的。所以即使是同一个款式的商品,它的图片还是会有很大差别的。
先展示一下文本检索是如何做到的。
image
image
这里采用了jieba来进行中文的分词。然后利用TF-IDF得到特征向量,并且计算第201个商品和其他距离并排序。结果可以看到还是比较准确的。
image
而对于图片而言,其实它是一个非结构化的数据,它肯定是不能做结巴分词的,也不能计算 TF-IDF 的。所以如何使用一些图片特征去描述图像,并且对图片的特征做具体的编码是关键。即使是同一张图片,它可能在不同的角度,不同的光照下面,所得到的结果是不一样的。而且有时两张图片看起来很相似,但是它们又可能描述的并不是同一个事情。同时图像检索任务或者说图像的特征提取任务是可以和图像分类以及物体检测任务相结合的。
那么如何提取图片特征呢?图片特征分为两类,一类是全局特征,一类是局部特征。全局特征就是关注图片的整体特征;局部特征就是关注图片的一些关键点,比如它的角点,以及一些颜色突然变换的这些角点、线条等。一般而言,现在使用的深度学习特征,都是全局特征。这个我们全局特征和图局部特征它的一些区别主要在于全局特征,它就是一张图片,它的特征都是一样的一张图片,不管它是什么颜色的,然后它是什么尺寸的,它的全局特征都是一样的。但是局部特征就不同如果一个图片它有大有小的话,说尺寸不同的情况下,他提取得到的关键点是不一样的。提取到的关键点是不一样的。
简单介绍一些图片特征类型。第一种是图片哈希。哈希是全局特征,它的使用方法就是将图片,利用哈希函数把它转变成具体的字符串。哈希值本质上的计算过程就是将图片进行缩小,然后计算特征,再把它转成字符串的过程。图片的希值计算起来比较简单,它也有一些缺点。图片的任何变化都会改变图片的哈希值。如果这个狗的图片角度发生了旋转,那么哈希值字符串也会发生变化。
image
第二种是利用图像的颜色直方图。颜色直方图也是一类全局特征,它本质上就是统计全局颜色的整体分布规律。它的优点是能够抵抗图像的旋转和平移,但是它的缺点是对颜色其实是很敏感的。如果对于图片的颜色做一些处理,比如加光照,或者增加对比度,颜色直方图就会发生改变。
第三种是利用图片的关键点。关键点是一个局部特征,它的本质就是利用一些关键点去描述原始图片。关键点有一些缺点,就是不同图片提取得到的关键点是不一样的,如果想要对于两张图片做关键点的匹配,距离计算其实是非常耗时的,速度很慢的。而且非常容易受到文字的影响,因为关键点的本质就是提取到这些角点或者说边缘比较突出的一些位置。这前三种都属于传统的特征提取方法。
第四个是深度学习的特征。深度学习特征是指把图片输入到卷积神经网络里,通过卷积层、池化层和一些其他操作,通过卷积神经网络提取的图片的 feature map ,通过 feature map 作为最终的图片特征。深度学习特征也是全局特征。利用刚才的数据集,可以使用卷积神经网络来计算相似图片。
首先需要将图片进行归一化,把图片都转化成256乘256尺寸的。归一化后的图片有利于进行批量的乘法。
image
加载训练模型。
image
接着就可以输入图片,进行一次正向传播,提取到它的特征并且存储。
image
然后再进行归一化,计算图片相似度。
image
可以看到结果还是比较准确的。与基于文本的检索相比,基于内容的检索更容易找到图片更为相似的商品。
image
在寻找同款的商品的时候,本质上可以画一个超平面,用这个超平面尽可能的把不同类的商品尽可能分割开。这一部分也是在做同款检索的时候也是非常重要的一部分,但是它是需要重新训练模型的,也是更高阶的一部分。
四、如何1秒计算百万次相似度
第一种方法可以先把图片特征做聚类。对于图片的特征它本身就是一个向量,那么就可以对向量做一个聚类。比如可以把原始的 1000 万张图片把它聚到 1000类以内,每个类别中心是一个 1 乘以 512 的一个向量。那么在做检索的时候,就可以先对距离进行判断,先判断一下它到底在哪一个聚类,哪个簇里面,然后再到这个簇里面去找相似就可以了,这样就可以降低时间复杂度。
第二种方法就是可以做量化。对于图片的特征,用具体的量化措施,这个量化的过程也是通过聚类来完成的。量化本质就是将图片的特征转变成一些整数。转成整数之后,就可以通过汉名距离或者编辑距离来计算相似度。
第三种方法就是把一个图片的特征构建到一个图里面。再找相似图片的时候,不单纯的去做计算,本质就是找这个图里面跟它相近的一些节点。这个技术称为 HNSW 。如果想要一秒钟之内完成这个百万次相似度计算,就不得不去尝试这三种方法。