图像搜索引擎 - 特征篇

在简介篇中我们简单说过图像特征,图像特征的提取有两种常用方式,一是提取例如SIFT特征,手工进行特征的筛选等,需要计算机视觉方面的先验性知识;二是使用当前很火的深度学习,训练出基于卷积神经网络模型的特征提取算子,某宝和某度用的就是这种方法。本文只涉及基于卷积神经网络提取出的特征。

关于特征

特征是计算机视觉的原材料,对最终模型的影响是毋庸置疑的。如果数据被很好的表达成了特征,通常线性模型就能达到满意的精度。那对于特征,我们需要考虑什么呢?

特征表示的粒度

就一个图片来说,像素级的特征根本没有价值。例如下面的摩托车,从像素级别,根本得不到任何信息,其无法进行摩托车和非摩托车的区分。而如果特征是一个具有结构性(或者说有含义)的时候,比如是否具有车把手(handle),是否具有车轮(wheel),就很容易把摩托车和非摩托车区分,计算机视觉和深度学习算法才能发挥作用。
图像搜索引擎 - 特征篇_第1张图片

初级(浅层)特征表示

计算机视觉领域的大牛们很早发现,复杂图形往往由一些基本结构组成。比如下图:一个图可以通过用64种正交的edges(可以理解成正交的基本结构)来线性表示。比如样例的x可以用1-64个edges中的三个按照0.8,0.3,0.5的权重调和而成。而其他基本edge没有贡献,因此均为0。
图像搜索引擎 - 特征篇_第2张图片

另外,大牛们还发现,不仅图像存在这个规律,声音也存在。他们从未标注的声音中发现了20种基本的声音结构.
图像搜索引擎 - 特征篇_第3张图片
其余的声音可以由这20种基本结构合成。
图像搜索引擎 - 特征篇_第4张图片

结构性特征表示

小块的图形可以由基本edge构成,更结构化,更复杂的,具有概念性的图形如何表示呢?这就需要更高层次的特征表示,比如V2,V4。因此V1看像素级是像素级。V2看V1是像素级,这个是层次递进的,高层表达由底层表达的组合而成。专业点说就是基basis。V1取提出的basis是边缘,然后V2层是V1层这些basis的组合,这时候V2区得到的又是高一层的basis。即上一层的basis组合的结果,上上层又是上一层的组合basis……。
图像搜索引擎 - 特征篇_第5张图片

直观上说,就是将有意义的小图块进行combine,就得到了上一层的feature,递归地向上learning feature。在不同object上做training是,所得的edge basis 是非常相似的,但object parts和object models 就会completely different了(那咱们分辨car或者face是不是容易多了):
图像搜索引擎 - 特征篇_第6张图片

全局特征

用 pre-trained googlenet 模型提取池化层pool5/7x7_s1的特征,该池化层之后则是分类器了,也就是说池化层pool5/7x7_s1是我们在神经网络中能够提取到的最高层次的feature了,姑且称之为全局特征吧。然后通过计算两幅图片的欧式距离确定其是否相似,感觉效果不错,至少能达到公司线上图像搜索引擎效果的90%。

全局特征来自神经网络的最高层,理论上表示的的不是edge basis 和object parts,而是高度抽象后的object models。为了验证全局特征是否表示高度抽象的object models, 也是为了验证全局特征在图像搜索引擎上的可行性,其中一次实验我以下面这幅图作为搜索图片(数据搞没了,这部分的demo没法截图……):
图像搜索引擎 - 特征篇_第7张图片
搜索到两幅图片如下:
图像搜索引擎 - 特征篇_第8张图片
图像搜索引擎 - 特征篇_第9张图片
这三幅图都是相似图片,但搜索结果中第一幅图的相似度远大于第二幅图。并且相似度高得搜索结果趋向于与第一幅一样的人物分布(左右各有一个人物)。经过大量实验对比发现:采用全局特征得到的相似图片都有一个共性,就是相似图片中的物体布局非常相似,趋向于在图片整体上有相似的结构。这个结果已经基本验证全局特征表示的是高度抽象的object models的猜想了。当然我们也可以通过可视化feature map验证全局特征的抽象层次。

局部特征

随着卷积神经网络层的深入,特征的抽象层次越高、局部表现力也越强,也即从无意义的像素级特征抽象到edge basis,再到object parts;但随着层的继续深入,特征逐渐丢失局部信息,趋向于表示object models、即趋向于从全局角度描述图片。卷积神经网络有很多隐层,不同数据集上同一隐层的特征抽象层次的表现力也不相同,所以我们没法准确的指明哪一中间层是最有表现力的,也即最能表现object parts的。最具表现力的中间层的选取可以参考论文《Exploiting Local Features From Deep Networks for Image Retrieval》。

我以 pre-trained googlenet的全连接层inception_4c/output作为特征提取层,提取出的特征称之为局部特征。理想状况下应该是分类目提特征,但由于同事准备的数据集没有做分类工作,也没法做分类工作,所以只能全部放一块儿进行搜索了。

搜索儿童自行车效果如下:
图像搜索引擎 - 特征篇_第10张图片

搜索女装效果如下:
图像搜索引擎 - 特征篇_第11张图片

对图像进行遮挡后搜索效果如下:
图像搜索引擎 - 特征篇_第12张图片
由于没有做分类工作,导致有手表乱入……

总结

上面的截图只是部分搜索结果,通过对大量搜索结果的分析发现:使用 pre-trained googlenet 模型作为特征算子,全局特征的搜索效果略优于局部特征的搜索效果。虽然全局特征的搜索效果是优于局部特征的,但全局特征向量由于其数据维度低、局部信息丢失、抽象层次太高,故很难适用在大规模数据的场景、很难实现更高要求的搜索效果;

其实最终的效果并不意外,pre-trained googlenet 模型主要用来对物体进行分类,其学习到的更多是如何识别物体的形状。使用该模型作为特征提取算子,提取的特征更多的是在形状层面上对图像进行描述。 对于一件连衣裙而言,pre-trained googlenet模型是没有学习到裙子的纹理、长度、腰型、风格等细节信息的,关于pre-trained googlenet 是否学习到这些信息,我们也可以通过可视化feature map来直观的看到。

我们有必要根据自己的数据集训练一个能够识别细节信息的模型。具体点说就是为每个类别的图片训练一个专用的模型,该模型只用来学习该类别图片的细节信息.,那么相应的提取出的特征也具有丰富的细节信息了。某宝就采用的是这种方式,为每个类目(例如连衣裙、羽绒服等)单独训练一个专用的模型作为特征提取算子。

参考资料

《Deep Learning(深度学习)学习笔记整理系列》
《Exploiting Local Features From Deep Networks for Image Retrieval》
《Deep Learning of Binary Hash Codes for Fast Image Retrieval》

你可能感兴趣的:(Search,Engine)