论文地址:https://arxiv.org/pdf/1711.02512.pdf
代码地址:https://github.com/filipradenovic/cnnimageretrieval-pytorch
《Fine-tuning CNN Image Retrieval with No Human Annotation》是2018年初发表在cs.CV上的论文——使用CNN精调技术实现无标注的图片检索。论文的作者之一Giorgos Tolias,也是R-MAC论文的作者。
论文重点
利用SfM模型处理训练数据,并用它在训练时选择代入模型的正例和反例,提升了模型的图像描述能力。
用训练数据迭代训练白化模型:在每次主模型迭代之后训练白化模型。
提出基于广义池化的自动调参GeM。
提出α-weighted query expansion(αQE)的后处理方法,加强检索的鲁棒性。
在Oxford Buildings, Paris, Holidays数据集上,使用基于AlexNet, VGG, ResNet的模型取得了更好的效果。
具体流程
首先将图片代入卷积层提取基本特征,将提取出的基本特征做GeM池化、l2归化一,提取到最终特征f;然后使用孪生网络Siamese对比不同图片的特征f(一般基于欧氏距离),计算误差函数,并对网络调参。
使用非人工标注的数据
文中涉及的数据主要针对建筑物,利用图片包含的地理位置信息和相机的信息使用structure-from-motion (SfM) 运动结构技术建立3D模型,SfM的输入是一些无序图片,使用图像聚类技术。使用SfM方法可过滤掉不匹配的图像,并可计算图像的相机位置,还能匹配图和子图。
使用SfM从无监督数据中找到相似的建筑物,作为训练集,从而绕过了手工标注的工作, 整个过程全自动进行。在建模过程中使用3D模型选择训练数据对,在后处理中也利用它得到更有辨识度的白化数据。
组织训练数据
一般训练数据包括待检索图片,正例和反例,需要选择hard negative有难度的反例和hard positive有难度的正例来训练模型。
选取hard negative是一个标准流程,一般用特征最为近似,而又不属于同一分类的图片作为hard negative,也需要注意反例不相互重叠。
选择hard positive时,如果有重要区域重叠的两张图,或是同一张图不同分辨率,将它们作为待检索图片和正例训练模型,会影响模型的泛化效果,论文中选择hard positive时,使用了以下三种方法:
- 使用所有有选正例中与待检索图片距离最远的作为hard positive,这种方法的弊端是,待检图和距离最远的正例可能匹配度很低,不利于高效调参。
- 使用3D模型选择正例,而不使用CNN提取的特征,比如选择3D观察点重合最多作为正例。
- 使用3D模型,随机选择观察点在一定范围之内的,且比例变化不大的图作为正例。
下图展示了三种选择正例方法的效果:
从下图可以看到使用不同方式组织训练集的结果:
广义平均池化
文中提出了基于广义平均池化generalized-mean(GeM)的可调参数的GeM。
常用的池化方法有最大池化:
平均池化
由于卷积层比全连接层提炼的特征效果更好,一般从CNN中提取出的特征形如WxHxK,W、H分别是图像经过卷积后的宽高,K是通道数,上式中的K也是通道数,等式右边的每一个f则代表每个通道中各个小块对应的特征值,也写作Xk。
最大池化是从某通道的所有特征中提取其中最大值作为该图的整体特征,而平均池化将所有小块的均值作为整体特征,由于一般的CNN网络最后都包括ReLU激活函数,因此特征值都是正的,这也避免了正负值相互抵消的问题。
广义平均池化公式如下:
简单地理解:广义平均池化介于最大池化和平均池化之间,当Pk趋近无穷时,它是最大池化,当Pk等于1时,它是平均池化。很多时候无法确定更偏重最大池化,还是平均池化,也就是无法确定Pk值的大小,文中提出的方法是通过训练求取最佳Pk。最终的特征f即可对初始的特征x求偏导,也可对Pk求偏导。
无论又何种方法,池化的目标都是将N小块的特征合成该通道的特征。最大池化的方法隐含地提取了局部的位置信息,比如第一行第二列的小块为该通道的最大值,最终得到的特征值是对该小块的描述,对两个图片该通道相似度的比较也是对小局部区域的比较。从下图可以看到,不同通道提取出不同的重点区域。
使用建筑物数据fine-tune后,图中的建筑物也更多被关注。
下图展示了使用广义池化方法之后,不同Pk对应关注到的不同区域——Pk值越大越关注局部。
论文的实验部分证明,GeM池化优于传统的平均池化和最大池化,学习单个P优于学习多通道各自的Pk,
孪生网络和损失函数
Siamese孪生网络是图片检索的常用方法,文中构造了一个二分枝网络,分枝使用相同构造方法并共享参数,两分枝分别提取需要对比的两张图片的特征,然后使用损失函数计算其差异。具体的编组方法是将一个待检图片,一个正例和五个反例编成一组,代入模型。
网络的输入是两张图片i,j,以及它们是否为同一物体label Y(I,j),1为同一物体,0为不同物体)。
误差函数Contrastive loss对比损失定义如下:
其中f是GeM池化并正则化后的特征,阈值τ用于衡量多大差异时被视为不同物体(loss margin一般为0.7-0.85)的边界值。
白化和降维
白化Whitening类似于PCA主成份分析,目的是降低数据的冗余性同时降维。一般在白化处理之后,特征的相关性比较低,且特征具有相同的方差。论文中使用3D模型和线性判别投射方式处理数据,投射将数据拆分成白化和旋转两部分,它定义了匹配项的协方差矩阵Cs:
和不匹配项的协方差矩阵CD
投影P可分解为:
白化部分是Cs平方根的逆矩阵,旋转部分是白化空间特征矩阵的主成分分析。论文中的实验也证明,相对于有损的PCA白化,经过学习的判别白化(learned discriminative whitening)效果最好。
后处理
在最终训练好模型之后,将数据通过模型转成特征,存储在数据库,需要查询时,将被查询的图片也代入模型计算特征,然后从数据库中检索与其欧式距离最近的图片,欧氏距离简单的算法就是计算两组值的内积,然后排序。
在预测阶段也有一些技巧,比如将图片缩放成不同尺度的多张图片代入模型,然后对提取到的不同特征再做GeM池化,经测试此处GeM池化的效果也高于平均池化。
query expansion(QE)也是目前图像检索的常用手段,最基本的方法是average query expansion(AQE),即搜索图片后得到前n个最近似的图片,取它们和待检索图片的均值,再进行二次搜索,这样用近似图像填补了待检索图像的某些特征。实际上,如果确定取前几个图片,以及如何给每个图片的加权,在不同的数据集中很难确定。论文中提出αQE,用待检索图片和数据库中图片的相似度加权,具体公式如下:
α由人工设定,当α为0时,αQE退变为AQE,使用此方法可提高查询的鲁棒性。文后的实验部分对比了不同α值对精度的影响。
从测试结果可以看到,使用AQE时,Oxford105k在参考图片变多时,精度有明显下降,而αQE对各数据集的效果都较好且平稳。
训练方法
下载源码
$ git clone [https://github.com/filipradenovic/cnnimageretrieval-pytorch](https://github.com/filipradenovic/cnnimageretrieval-pytorch)
训练方法:
$ python3 -m cirtorch.examples.train YOUR_EXPORT_DIR --gpu-id '0' --training-dataset 'retrieval-SfM-120k' \
--test-datasets 'roxford5k' --test-whiten 'retrieval-SfM-30k' \
--arch 'resnet50' --pool 'gem' --loss 'contrastive' --loss-margin 0.85 \
--optimizer 'adam' --lr 5e-7 --neg-num 5 --query-size=200 --pool-size=500 \
--batch-size 5 --image-size 362
测试方法:
$ python3 -m cirtorch.examples.test --gpu-id '0' --network-path 'retrievalSfM120k-vgg16-gem' \
--datasets 'oxford5k,paris6k,roxford5k,rparis6k' \
--whitening 'retrieval-SfM-120k' \
--multiscale '[1, 1/2**(1/2), 1/2]'
训练和测试数据均在源码的data目录下,如果使用作者提供的建筑物图片训练,不需要修改,运行train或test即可。如果想用自己的数据训练模型,则需要在data目录下安装自己的数据,改动DataSet或者构造数据目录下的pkl文件,它用于存放使用的数据及其标注信息。