Bag of words模型最初被用在文本分类中,将文档表示成特征矢量。它的基本思想是假定对于一个文本,忽略其词序和语法、句法,仅仅将其看做是一些词汇的集合,而文本中的每个词汇都是独立的。简单说就是讲每篇文档都看成一个袋子(因为里面装的都是词汇,所以称为词袋,Bag of words即因此而来),然后看这个袋子里装的都是些什么词汇,将其分类。如果文档中猪、马、牛、羊、山谷、土地、拖拉机这样的词汇多些,而银行、大厦、汽车、公园这样的词汇少些,我们就倾向于判断它是一篇描绘乡村的文档,而不是描述城镇的。举个例子,有如下两个文档:
文档一:Bob likes to play basketball, Jim likes too.
文档二:Bob also likes to play football games.
基于这两个文本文档,构造一个词典:
Dictionary = {1:”Bob”, 2. “like”, 3. “to”, 4. “play”, 5. “basketball”, 6. “also”, 7. “football”,8. “games”, 9. “Jim”, 10. “too”}。
这个词典一共包含10个不同的单词,利用词典的索引号,上面两个文档每一个都可以用一个10维向量表示(用整数数字0~n(n为正整数)表示某个单词在文档中出现的次数):
1:
1,2,1,1,1,0,0,0,1,11,2,1,1,1,0,0,0,1,1
2:
1,1,1,1,0,1,1,1,0,01,1,1,1,0,1,1,1,0,0
向量中每个元素表示词典中相关元素在文档中出现的次数(下文中,将用单词的直方图表示)。不过,在构造文档向量的过程中可以看到,我们并没有表达单词在原来句子中出现的次序(这是本Bag-of-words模型的缺点之一,不过瑕不掩瑜甚至在此处无关紧要)。
SIFT特征虽然也能描述一幅图像,但是每个SIFT矢量都是128维的,而且一幅图像通常都包含成百上千个SIFT矢量,在进行相似度计算时,这个计算量是非常大的,通行的做法是用聚类算法对这些矢量数据进行聚类,然后用聚类中的一个簇代表BOW中的一个视觉词,将同一幅图像的SIFT矢量映射到视觉词序列生成码本,这样每一幅图像只用一个码本矢量来描述,这样计算相似度时效率就大大提高了。
当然,在提取sift特征的时候,可以将图像打成很多小的patch,然后对每个patch提取SIFT特征。
总结一下,整个过程其实就做了三件事,首先提取对 n 幅图像分别提取SIFT特征,然后对提取的整个SIFT特征进行k-means聚类得到 k 个聚类中心作为视觉单词表,最后对每幅图像以单词表为规范对该幅图像的每一个SIFT特征点计算它与单词表中每个单词的距离,最近的+1,便可得到该幅图像的码本。实际上第三步是一个统计的过程,所以BOW中向量元素都是非负的。Yunchao Gong 2012年NIPS上有一篇用二进制编码用于图像快速检索的文章就是针对这类元素是非负的特征而设计的编码方案。
看完了这些理论以后,相信已经对BOW模型
在这个连接上有BOW的MATLAB实现代码及图片数据库:https://github.com/lipiji/PG_BOW_DEMO,这是这个连接的作者关于BOW的博客说明http://www.zhizhihu.com/html/y2011/3536.html
下面是我看这个代码所有的一点收获:
结合代码讲一下bag of visual word 的模型建立过程:1、利用sift等特征提取算法从每张图片中提取特征点也就是视觉单词。在代码中,每张图片是200*200大小,然后步长是8,将图片分成16*16的小patch,这样就有576个小patch,在每个小patch上都进行sift提取关键点,每个小patch上有一个关键点,这样就有576个关键点,也就是每张图片最终变成了576个128维的向量(sift特征点是128维的),也就是576*128这样大小的一个矩阵。图片包括训练样本和测试样本一共有360张图片,所以数据一共就是360*576*128. 2、利用K-means进行聚类,构建词汇表vocabulary。在代码中是找了300个聚类中心,也就是300*128,聚类中心个数的选取从几百到上千不等,一般数据越大,聚类中心越多。聚类的数据是训练数据240*576*128和测试数据120*576*128,最大迭代次数100,聚类完成后得到300个聚类中心,每个是1*128维的向量。3、利用得到的聚类中心得到词汇表以后,对360张图片进行直方图统计,也就是看每张图片中的576个关键点与哪个聚类中心的距离最小(最相似),然后再最近的那个聚类中心所代表的1-300之间的数上加1,这样最终得到了BOW的数据300*360大小的矩阵,这里面300*240是训练数据,300*120是测试数据。注意由于这里每张图片的关键点的数目都是一样的,所以归一化的影响并不是特别的关键,但是如果每张图片上关键点的数目不是一样的,那就必须进行归一化,也就是将词数变成词频,就是除以总点数。
以上是基本的BOW建立的过程,作者的程序中有一个pyramid BOW的程序CompilePyramid,这里面是spatial pyramid程序。BOW与pyramid BOW在统计每张图的词频时是一样的 ,关键是对这些词频的处理不一样,BOW是全局进行统计词频,而pyramid BOW如名字所示,是分层次的,在代码中,是首先将图片分成4*4小块,对每小块进行300个聚类中心的词频统计,并用2^-1进行加权,然后在将图片分成2*2小块进行300个聚类中心的词频统计,并用2^-2进行加权,最后再对整个图片全局的直方图进行直方图统计,并用2^-2进行加权,最后将这些直方图连在一起,这样最终的数据是6300*360这样的数据去进行训练。也就是说,源程序里面是有两种词袋的数据结果,BOW和pyramid BOW,然后作者用BOW+径向基核函数的SVM进行分类,精度是77.5%,pyramid+径向基核函数的SVM进行分类,精度是82.5%;作者有自己定义了一种和函数,称之为inter吧,BOW+inter核函数的分类精度是81.6667%,pyramid BOW+inter核函数的分类精度是最高的,为90.8333%。