原文
NetVLAD 是一个较早的使用 CNN 来进行图像检索或者视频检索的工作,后续在此工作的基础上陆续出了很多例如 NetRVLAD、NetFV、NetDBoW 等等的论文,思想都是大同小异。
VLAD 和 BoW、Fisher Vector 等都是图像检索领域的经典方法,这里仅简介下图像检索和 VLAD 的基本思想。
图像检索(实例搜索)是这样的一个经典问题:
1、我们有一个图像数据库 I i I_i Ii, 通过函数可以得到每一个图像的特征 f ( I i ) f(I_i) f(Ii)
2、我们有一个待查询图像 q q q 通过函数得到它的特征 f ( q ) f(q) f(q)
3、则我们获得的欧氏距离 d ( q , I ) = ∣ ∣ f ( q ) − f ( I ) ∣ ∣ d(q,I)=||f(q)-f(I)|| d(q,I)=∣∣f(q)−f(I)∣∣ 应该满足越相近的图像 d ( q , I ) d(q,I) d(q,I) 越小。
而 VLAD (Vector of Locally Aggregated Descriptors)则是图像检索中一个经典方法,也就可以理解为怎么获得上述的 f f f 的方法,记为 f V L A D f_{VLAD} fVLAD 。通常在传统方法中我们会获得一系列的局部特征(SIFT、SURF、ORB)之类,假设为 N 个 D 维的局部特征(通常 N 可能比较大,而且每幅图特征多少不一,N 可能数量也不一定),我们希望通过这 N * D 维特征获得一个可以表示图像全局 K * D 维特征的方法(通常K是我们指定的数目,例如128维)。VLAD 的主要流程如下:
1、对全部 N * D 维局部特征进行 K-Means 聚类获得 K 个聚类中心,记为 C k C_k Ck
2、通过以下公式将 N * D 维局部特征编写为一个全局特征 V,特征向量维数为 K * D,其中 k ∈ K , j ∈ D k∈K, j∈D k∈K,j∈D,公式如下: V ( j , k ) = ∑ i = 1 N a k ( x i ) ( x i ( j ) − c k ( j ) ) ,( 1 ) V(j,k)=\sum_{i = 1}^{N}a_k(x_i)(x_i(j)-c_k(j)),(1) V(j,k)=i=1∑Nak(xi)(xi(j)−ck(j)),(1)
其中 x i x_i xi 为第i个局部图像特征, c k c_k ck 为第k个聚类中心, x i x_i xi 和 c k c_k ck 都是 D 维向量。 a k ( x i ) a_k(x_i) ak(xi) 是一个符号函数,当且仅当 x i x_i xi 属于聚类中心 c k c_k ck 时, a k ( x i ) = 1 a_k(x_i)=1 ak(xi)=1 ,否则 a k ( x i ) = 0 a_k(x_i)=0 ak(xi)=0。
经过上面对于经典 VLAD 方法的解释,我们可以看出来 f V L A D f_{VLAD} fVLAD 是一个将若干局部特征压缩为一个特定大小全局特征的方法,通过聚类,实现了将特征降维,同时用特征与聚类中心的差值作为新的特征值,在实践中 VLAD 方法具有较好的检索效果。
经典 VLAD 方法显然是一个不可导的函数,其中主要不可导的地方在于 a k ( x i ) a_k(x_i) ak(xi) 这样一个符号函数,因此为了将 VLAD 变可训练的函数,必须将其变成可微计算。作者将 a k ( x i ) a_k(x_i) ak(xi) 平滑化:
a ˉ k ( x i ) = e − α ∣ ∣ x i − c k ∣ ∣ 2 ∑ k ’ e − α ∣ ∣ x i − c k ’ ∣ ∣ 2 ∈ ( 0 , 1 ) ,( 2 ) \bar{a}_k(x_i)=\frac{e^{-\alpha||x_i-c_k||^2}}{\sum_{k^’}e^{-\alpha||x_i-c_k^’||^2}}∈(0,1),(2) aˉk(xi)=∑k’e−α∣∣xi−ck’∣∣2e−α∣∣xi−ck∣∣2∈(0,1),(2)
这里面 α α α 是一个正值参数,显然当 α → ∞ α→∞ α→∞ 时, a ˉ k ( x i ) \bar{a}_k(x_i) aˉk(xi) 更趋近于 0 和 1 的两级。
再将 − α ∣ ∣ x i − c k ∣ ∣ 2 -\alpha||x_i-c_k||^2 −α∣∣xi−ck∣∣2 展开,显然 e − α ∣ ∣ x i ∣ ∣ 2 e^{-\alpha||x_i||^2} e−α∣∣xi∣∣2 可以被约掉,因此得到:
其中 w k = 2 α c k w_k=2αc_k wk=2αck, b k = − α ∥ c k ∥ 2 b_k=−α∥c_k∥^2 bk=−α∥ck∥2,其实仔细观察这个公式,就是一个 softmax。
这样 VLAD 公式就被改写为:
a ˉ k ( x i ) = ∑ i = 1 N e w k T x i + b k ∑ k ˊ e w k ˊ T x i + b k ˊ ( x i ( j ) − c k ( j ) ) ,( 4 ) \bar{a}_k(x_i)=\sum_{i=1}^N\frac{e^{w_k^Tx_i+b_k}}{\sum_{\acute{k}}e^{w_{\acute{k}}^Tx_i+b_{\acute{k}}}}(x_i(j)-c_k(j)),(4) aˉk(xi)=i=1∑N∑kˊewkˊTxi+bkˊewkTxi+bk(xi(j)−ck(j)),(4)
显然这里面 w k w_k wk、 b k b_k bk 和 c k c_k ck 都是 NetVLAD 需要学习的参数。
我们这样将 c k c_k ck 作为学习参数有什么好处呢,论文中用了一幅图进行了直观解释:
传统 VLAD 的中心是聚类出来的,没有监督的标签数据 c k V L A D c_k^{VLAD} ckVLAD,在聚类时我们使用了很多图像这些图像的描述符之间没有关系,那么也就很可能把本来不是一个物体的描述符聚为一类,使得我们原本期望的类内描述符都是一个物体的 feature 不太容易达到。而在使用监督数据进行训练时,我们可以已知图像数据属于同一物体,那么训练时就可以只把属于同一物体的特征聚在一起而把不是的划分到其他类别,这样就可能学习出一个更好的 c k V L A D c_k^{VLAD} ckVLAD 聚类中心,使得最终的特征更有区分度。
首先,由于是 NN 的方法,我们这里使用 CNN Feature 代替了传统 VLAD 中的 N 个局部描述子,CNN 是一个全局的特征,它的 Feature Map 是 W * H * D 大小,那么类比于我们之前的传统方法 N * D,我们这里 NetVLAD 目标就是将 W * H * D (N=W * H)的特征转换为 K * D 的特征;
其次,我们将整个 NetVLAD 看做一个 pooling layer,它的作用是实现降最终和 VLAD 一样获得我们想要的 K * D 维描述子。
具体实现上,我们就分步骤来做,这部分作者的 PPT 里面有张图非常清晰:
1、实现 z k = w k T x i + b k z_k=w_k^Tx_i+b_k zk=wkTxi+bk,也就是公式中的蓝色部分,论文里直接通过一个1x1的卷积来做。这也是1x1卷积的一个应用;
2、实现 σ k ( z ) = e z k ∑ k ′ e z k ′ σ_k(z)=\frac{e^zk}{∑_{k^′}e^zk^′} σk(z)=∑k′ezk′ezk,也就是公式中的黄色部分,如之前所述这实际上就是一个 softmax 公式,论文里直接通过一个 softmax 来做;
3、实现 x i ( j ) − c k ( j ) x_i(j)−c_k(j) xi(j)−ck(j),也就是公式中的绿色部分,这部分就是一个减法,直接用一个 VLAD core来做;
4、1~3已经实现了 V ( j , k ) V(j,k) V(j,k) 的计算了,后面按照 All about VLAD 论文还要对 V ( j , k ) V(j,k) V(j,k) 做两步简单的归一化(这篇论文证明了归一化可以提升检索性能),包括:
1)intra-normalization
这个主要意思是将每一个 VLAD block(也就是每个聚类中心的所有残差)分别作 l2 normalization。
2) l2 normalization
这个是将所有 VLAD 特征一起做 l2 normalization。
在图像检索中,训练通常需要明确的图像到底是哪个物体的标注。而论文针对的领域是地点识别,因此可以利用图片的位置信息,将 Google Street View 的数据作为训练图片,将同一地点、不同视角、不同时间的数据作为同一物体标签进行训练。相对并没有明确的标注图上面都是那个物体,只是说这几幅图中可能看到同样的一个物体,数据比较容易获取。这在机器人领域同样也是可行的。
我们将整个网络看做一个特征提取函数 f θ f_θ fθ,那我们的目标自然就是:对于一个需要检索的图像 q q q,我们有一个数据库 I I I,我们希望位置最近的图片 I i ∗ I_{i∗} Ii∗ 的特征欧氏距离,比其他所有图片 I i I_{i} Ii 的距离都要小:
d θ ( q , I i ∗ ) < d θ ( q , I i ) ,( 5 ) d_θ(q,I_{i∗})
然而理想情况是这样,如刚才小节所述我们实际上不能获取最近的图片 I i ∗ I_{i∗} Ii∗ ,但我们可以获取相近的图片集合(作为正样本) p i ∗ q p^q_{i*} pi∗q,这些正样本集合一定包含了我们想要的 I i ∗ I_{i∗} Ii∗ ,但是我们不知道是哪一个;同样,我们也可以获取绝对不可能是同一物体的负样本集合 n j q n_j^q njq ,比如远离所选地点的图片。那么我们至少可以期望获得这样的结果:所有正样本集合的特征距离,应该要比负样本集合的特征距离要小:
d θ ( q , p i ∗ q ) < d θ ( q , n j q ) ,( 6 ) d_θ(q,p^q_{i*})
并且正样本中距离最近的应该就是我们想要的最近图片:
p i ∗ q = a r g m i n d θ ⏟ p i q ( q , p i q ) ,( 7 ) p_{i∗}^q=\underbrace{argmind_θ}_{p_i^q}(q,{p_i^q)},(7) pi∗q=piq argmindθ(q,piq),(7)
据此,我们构造如下 loss:
L θ = ∑ ⏟ j l ( m i n ⏟ i d θ 2 ( q , p i q ) + m − d θ 2 ( q , n j q ) ) ,( 8 ) L_θ=\underbrace{∑}_jl(\underbrace{min}_id_θ^2(q,p_i^q)+m−d_θ^2(q,n_j^q)),(8) Lθ=j ∑l(i mindθ2(q,piq)+m−dθ2(q,njq)),(8)
其中 l ( x ) = m a x ( x , 0 ) l(x)=max(x,0) l(x)=max(x,0) 也就是所说的 hinge loss,m是一个常量表示我们给负样本设置的 margin。这个 loss 与 triplet loss 是很像的。
作者在附录中给出了详细的实现细节,网络提取部分作者使用 VGG-16 但做了一些修改,对于 VLAD 的聚类中心使用 K=64,m=0.1。
训练 lr = 0.001 或 0.0001,优化器 SGD,momentun 0.9,weight decay 0.001,batchsize=4 turples。这里不一一例举。具体还是看作者的代码比较好。
1、PDF:NetVLAD: CNN architecture for weakly supervised place recognition
2、PPT:cvpr16_NetVLAD_presentation.pptx
3、Code:
https://github.com/Relja/netvlad (作者的,使用 MatConv 框架)
https://github.com/sitzikbs/netVLAD/blob/master/netVLAD.py (第三方实现,不过只有 VLAD layer 部分)
https://github.com/shamangary/LOUPE_Keras (第三方实现,不过只有 VLAD layer 部分)