实训项目:以图搜图

以图搜图

一个运用机器学习来搜女包的项目,以下是项目过程介绍&个人感想

一、实训简介

  这次大三为期一个半月的实训,我参与的实训项目是做的是一个以图搜图的应用,用的是京东上的女包的数据。考虑到这样的一个场景,在网上浏览网页的时候遇到喜欢的包包,但是在电商网站的搜索栏中难以用语言描述出来,所以我们提供一个以图搜图的应用,以图片代替语言的形式,在某些语言难以描述清楚的情况下,帮助客户快速、准确找到想要的商品。

我们做这款应用的大概流程是:
>
- 从京东网站上抓取图片和文本数据
2. 利用caffe训练的模型抽取特征
3. 把抽取到的特征压缩成二进制码
4. 建立分段哈希表

然后客户传入图片数据,经过特征抽取和压缩成二进制码,再与分段哈希表中的数据做比较,找到相似的女包后,应用会返回电商的链接。


二、实训项目流程

1.抓取&分析数据

  实现以图搜图的功能首先需要获得训练数据,需要抓取包包的图片和标签信息。 使用了Python的Request库,我这里抓取的是京东的数据,主要考虑以下几个原因:
>
- 京东的商品比较多,适合用于需要大数据量的机器学习训练
- 京东的标签比较齐全,方便我们训练时候标签的筛选
- 京东的分类的商品格式比较规范,便于我们抓取

  抓取数据完数据之后需要对数据所在的网页进行分析,提取出我们需要的信息,这里用到了Python的BeautifulSoup的库。BeautifulSoup的库会把html网页用树状结构打开,然后根据标签信息找到对应的数据

  BeautifulSoup使用到的函数我是参考官方给的文档,附上文档链接:
  http://www.crummy.com/software/BeautifulSoup/bs4/doc/


2.训练模型&抽取特征

  获取完数据后,我们需要根据数据的图片信息和标签信息训练一个用于分类模型,训练好的模型会被用来做抽取特征。

(1)模型训练

  我用了caffe作为深度学习的工具来训练模型,所以首先需要做的就是配置caffe需要的环境,然后下载caffe源码编译安装,附上caffe的安装链接:http://caffe.berkeleyvision.org/installation.html
  我用的是Ubuntu的操作系统,配置文件的网页链接:
http://caffe.berkeleyvision.org/install_apt.html
  

  关于caffe的train和test都在caffe的首页有说明,链接:http://caffe.berkeleyvision.org/

  用的是googlenet的网络结构来训练,初始化是用训练好的googlenet模型

(2)抽取特征

  用训练好的模型,抽取分类前一层的数据作为特征,原因是前一层的特征离分类结果最近,对分类结果影响最大,也即最能代表这个图片

  由于我们的分类是多标签的,同时我们的输入是通过图片的形式输入而不是lmdb数据库,所以需要对googlenet的网络结构的输入和输出做修改
>
- 原来的googlenet用的是lmdb作为输入,也就是DataLayer层,但是我们现在改成直接输入图片,所以要改成ImageDataLayer层,同时也要改网络的配置文件train_val.prototxt
2. 多标签的修改需要修改ImageDataLayer层,把int label改成vector label,以及输入的时候接收多个输入等
3. 由于是多标签,所以我们的输出层不能用softmax这种只有一个分类的loss function,这里用的是欧式距离


3.ITQ

  在我们有了抽取后的特征后,需要把这些特征压缩成二进制码,目的首先是为了压缩存储空间,同时方便哈希做快速匹配。除此之外,ITQ还通过旋转矩阵来减少量化误差,作用也是加速哈希表的匹配

  ITQ是通过循环迭代,分别更新二进制码B和旋转矩阵R,最后得到一个量化误差最小的旋转矩阵R以及旋转后压缩成的二进制码B,二进制码B用于建立哈希表,而旋转矩阵R用于传入图片的浮点数特征旋转后压缩成二进制码。

  具体细节:
>
1. 进行ITQ前,先要对数据集中的文件做中心化处理,同时把每一列的均值记录下来,用于新图片特征的预处理
2. 固定R更新B,随机生成旋转矩阵R,对输入的数据集V做矩阵乘法,得到V*R。B矩阵大小和V*R矩阵一样,判断V*R矩阵每一个元素是否大于0,若大于0,在B矩阵中相同位置为1,否则置为-1
3. 固定B更新R,对得到的B矩阵的转置和V矩阵做矩阵乘法,然后对乘法的结果做SVD,得到S,O,St三个矩阵,然后令R等于St的转置和S的转置做矩阵乘法后的结果
4. 用2和3中得到的B和R,循环迭代更新50次,可以得到一个较优的旋转矩阵


4.MIH

  MIH即Multi-Index Hashing,是对位数较大情况下的二进制码做快速哈希的一种办法。位数较大的时候,建哈希表耗费的空间太大,MIH用分段的方法大大减少了空间的耗费,同时,也提供较快的速度。

  MIH的具体流程是:
>
1. 将n位二进制码分段,分成m段,每段b位
2. 根据每小段来建哈希表,原来需要2^n个哈希桶,而现在只需要m*2^b个哈希桶,其中m*b = n
3. 匹配的时候,把需要匹配的二进制码把每个小段匹配到的二进制码作为候选码。
4. 由于候选码远小于数据集,所以只需要对候选码做一次线性遍历,筛选出符合要求的就可以

  关于MIH有以下几个地方需要关注:
>
- 抽取出来的二进制码可能存在某些列的属性比较类似,所以需要根据每一列的方差进行重新排序,使得每段中列的方差和相近,这样能大大减少匹配的候选码的个数,也即大大减少线性遍历需要的时间
- 显然,当每小段位数越长,哈希表耗费的空间就越多,但是候选码就越少。当每小段位数越短,哈希表虽然耗费的空间就越少,但是候选码就越多,时间耗费增加。每段二进制码的位数,根据空间耗费和候选码个数之间做平衡来决定

实训感想

  本次实训是大学以来收获最大的一次,不仅是因为时间长,同时也有团队合作的体验,当然对最后做出的项目制品也比较满意。

  由于这次实验做的是一个比较贴近生活的应用项目,所以我们考虑的问题,以及优化的时候会更考虑客户的使用体验,如返回结果怎么展示,等待时间不能太长以及训练数据的抓取都要从电商网站上抓取,这对平时都是老师给我们提供数据和教程,接触项目较少的我来说是一次不小的挑战,但是很幸运,最终也顺利的完成了这次的实训内容。

你可能感兴趣的:(机器学习)