基于文字的图片检索目前已经很成熟,但在很多情况下并不能满足用户的需求。比如,用户向在大街上看到别人拎了一个很漂亮的包包,也产生购买冲动,所以拍下了这个包包的照片,根据这幅照片找到这个包包的销售价格和商家。再比如,用户偶然看到一些不错的图片,想找到相同或相似的图片。再比如,人脸识别,通过图片获取该图片的内容信息。这些情况下,传统的图片搜索引擎无能为力。
一种基于图片内容的图片理解技术就非常必要了,图片理解引擎基本代表了图片检索和识别的主流技术。图片理解的目标是让计算机对图片内容进行准确完善的表述,目前这个目标还比较遥远,但是在其他方面图片理解已经有了较广泛的应用。目前图片理解引擎的主要应用场景有:1人脸理解;2商品或物体搜索。目前相似图片搜索引擎有: TinEye,Google,Baidu (百度识图)等等。商品图片搜索引擎有Like (被Google收购),Ebay,Amazon,淘淘搜等等。人脸理解方面代表的公司有Google,Facebook等。可见,目前主流的互联网公司均在图片理解方面进行了大量的投入。这些下面主要介绍下我在针对这三个方面所做的工作进展情况,也欢迎感兴趣同学一起讨论。
图片理解,通常要对图片进行特征提取,利用这些特征对图片内容进行描述,然后对这些特征在特征数据库中进行特定方式的检索和处理。整个图片理解引擎开发中涉及到的图片特征主要可以分为三类:Hash特征,局部特征,以及深度特征。
Hash特征,有Mean-Hash,DCT-Hash等,主要对每张图片生成一个“指纹”(fingerprint)字符串,然后比较不同图片的指纹,结果越接近,就说明图片越相似。Hash特征优点是速度快,算法简单;缺点也很严重,对背景,旋转,形变都非常敏感,所以一般用来做重复图片过滤。
局部特征,常用的有SIFT,SURF,BRIEF。局部特征点是图像特征的局部表达,它只能反正图像上具有的局部特殊性,所以它只适合于对图像进行匹配,检索等应用。对于图像理解则不太适合。而后者更关心一些全局特征,如颜色分布,纹理特征,主要物体的形状等。
深度特征,这是一种全局特征。我的实现中采用卷积神经网络作为特征提取网络(Convolutional Neural Network,CNN)。卷积神经网络对几何变换、形变、光照具有一定程度的不变性。卷积神经网络主要用三种结构来实现对输入的局部平移不变性:局部接受域、权值共享和子采样。卷积神经网络的训练需要大量的人工标注数据,为每个数据人工设置类标号是非常费时和枯燥的。然而,为了使得监督卷积神经网络通过训练具有较高的泛化能力,需要大量具有类标号的训练样本,这也是制约临督卷积神经网络在实践应用的主要因素。
引擎处理图片的量级少则数万多则上千万过亿,尤其在商品检索和移动端的商品或物体搜索所涉及的检索对象是整个商品目录,因此必须对特征进行压缩以及检索策略进行优化来满足引擎的时间和空间性能要求。
压缩
聚类(clustering),将对象的集合分成由类似的对象组成的多个类的过程。可以实现对对象的压缩。引擎实现中,采用K-Means聚类方式,距离衡量采用余弦相似度。实验过程中,发现聚类方式可以极大比例的压缩特征数据库,但是也存在相当严重的问题,即聚类描述的相似度是不具备严格传递性的。一个简单的例子,如下图所示,父、母与子具备一定的相似度,归为子类,但很明显父、母之间是不存在相似性的。因上原因,聚类在引擎索引和压缩中作为一个补充策略使用。
LSH Hash(Locality Sensitive Hashing),即位置敏感哈希函数。与一般哈希函数不同的是位置敏感性,也就是散列前的相似点经过哈希之后,也能够在一定程度上相似,并且具有一定的概率保证。这种策略,作为引擎的主要压缩策略使用。
PCA也就是Principal Components Analysis,主成份分析,寻找最小均方意义下,最能代表原始数据的投影方法。这一点跟LSH很像,不过LSH只是概率上的保证,PCA是严格的最小均方意义下的。
检索
构建特征库的森林,森林中的每棵树代表特征库的一个类别,比如人脸的深度特征,箱包的局部特征等均建立一个树。采用类似K-D tree的检索方式,保证检索的速度。采用分类别建立树的目的是保证检索的准确率和速度。
之前文章介绍过我实现的基于CNN的人脸识别模块的应用,人脸理解是在之前的人脸识别模块基础上增加了以下的功能:基于人脸的性别检测,基于人脸的年龄检测,颜值计算,人脸五官属性打分。以上的功能实现的方式基本相似,下面以人脸识别为例,简述人脸理解模块的实现。
人脸识别,CNN网络训练数据集,采用CASIA-WebFace,12000人,400000图。 选用人脸和正向化人脸的实际意义区域,包括全头部,全脸,半脸等共8个patch。所以需要训练的网络也只需要8个。网络结构,即包含5个卷积层和3个全连接层。特征256维度进行分类。整个处理流程见下图所示。
数据预处理过程包括:灰化,人脸检测,姿态检测,landmark检测,alignment,scale一致性变化。
1. RGB图片不如灰度图片效果好,灰度图片已经包含了人脸信息,而RGB图片更容易受到光照等环境因素影响,引入冗余信息。
2.根据检测到的landmark,进行scale一致性变化。 一致性变化保证了人脸图片在统一的尺度下进行特征提取。
3.人脸正向化,正向化处理的有助于分类准确率的提升。
CNN网络结构
• 输入:64×64大小的图片,1通道
• 第一层卷积:9×9大小的卷积核96个
• 第一层max-pooling:3×3的核。
• 第二层卷积:5×5卷积核256个
• 第二层max-pooling:3×3的核
• 第三层卷积:与上一层是全连接,3*3的卷积核384个
• 第四层卷积:3×3的卷积核384个
• 第五层卷积:3×3的卷积核256个
• 第五层max-pooling:2×2的核。
• 第一层全连接:4096维
• 第二层全连接:256维
• Softmax层:输出为12000
每个patch都会得到一个特征向量,对特征向量进行一定方式的融合作为最后人脸验证的特征,实现中共采用了三种方式,以应对不同的场景需求。如下图所示:
1.多组联合特征 -> 多组PCA -> 多组Joint Bayesian ->SVM , 这种方式准确率最高,但是速度最慢。
2.多组特征 ->多组Joint Bayesian -> SVM,该方式准确率次之,速度次之。
3.多组特征 ->余弦距离 -> SVM,速度最快,准确率最低。
采用方式1的特征融合方式,在LFW上测试EER为98.89%,如下图所示基本逼近业界目前的最好水平99%。
人脸库的构建
特征提取和检索完成后,则需要构建人脸数据库,构建流程如下图所示。对于一个人推荐上传采用三幅不同姿态的脸部图片,以提高准确率。构建过程如下图所示。
实现的框架与人脸理解模块基本类似,下面主要描述实现不同的方面。
预处理主要体现在复杂背景的商品图片的商品提取,以及背景弱化,需要一定的人工辅助。具体的算法采用基于主颜色的区域增长。效果如下图所示黄色线条表示人工标注的检索区域。
人脸理解只使用深度特征,而对于商品的检索还是用了局部特征(SIFT)和主颜色特征。同时深度特征提取网络采用VGG Net,没有像人脸理解模块那样进行训练。
主颜色特征指商品的主要颜色,对于主要颜色的提取分两种情况。1对于背景简洁的商品图片,先检测图片的显著性区域,然后计算显著性区域的色彩直方图,选取主要的颜色类型。2对于背景复杂的图片,需要人工标注出检索目标的位置,并对该位置进行主要色彩分析,方法同1。
单一尺度图片从VGG Net的特征维度,太大(4096),采用PCA进行压缩到300维度。然后采用LSH进行编码,构建LSH Trees。
SIFT特征的处理,先采用对特征进行聚类,得到每幅图片的SIFT特征索引组成的向量。向量的位置表示聚类中心的索引,该位置的值表示在具有该类中心的特征点个数。
前面说到,K-D Tree 由于是按照维度进行分裂建树的,所以在高维度的大数据量情况下会消耗大量的内存空间。所以对特征组织时采用了LSH中的映射超平面进行分裂建立树结构。
首先感谢吴良波同学提供的商品图片库,展示的功能是在23w的“箱包”商品中检索用户输入图片的同款商品或相似商品。由于所用的检索商品库不同,所以就没有做与其他公司的检索引擎做横向对比。
目前的检索速度在1.5s/幅图片,返回最相似的四个商品。
简洁背景图片的商品检索
复杂背景图片的商品检索
本文来自网易实践者社区,经作者祁斌川授权发布。