这部分来自:DeepLearning-500-questions#5
NetVLAD是论文《NetVLAD: CNN Architecture for Weakly Supervised Place Recognition》提出的一个局部特征聚合的方法。
在传统的网络里面,例如VGG啊,最后一层卷积层输出的特征都是类似于Batchsize x 3 x 3 x 512的这种东西,然后会经过FC聚合,或者进行一个Global Average Pooling(NIN里的做法),或者怎么样,变成一个向量型的特征,然后进行Softmax or 其他的Loss。
这种方法说简单点也就是输入一个图片或者什么的结构性数据,然后经过特征提取得到一个长度固定的向量,之后可以用度量的方法去进行后续的操作,比如分类啊,检索啊,相似度对比等等。
那么NetVLAD考虑的主要是最后一层卷积层输出的特征这里,我们不想直接进行欠采样或者全局映射得到特征,对于最后一层输出的W x H x D,设计一个新的池化,去聚合一个“局部特征“,这即是NetVLAD的作用。
NetVLAD的一个输入是一个W x H x D的图像特征,例如VGG-Net最后的3 x 3 x 512这样的矩阵,在网络中还需加一个维度为Batchsize。
NetVLAD还需要另输入一个标量K即表示VLAD的聚类中心数量,它主要是来构成一个矩阵C,是通过原数据算出来的每一个
ak=0,计算每一个x和它聚类中心的残差,然后把残差加起来,即是每个类别k的结果,最后分别L2正则后拉成一个长向量后再做L2正则,正则非常的重要,因为这样才能统一所有聚类算出来的值,而残差和的目的主要是消减不同聚类上的分布不均,两者共同作用才能得到最后正常的输出。
输入与输出如下图所示:
中间得到的K个D维向量即是对D个x都进行了与聚类中心计算残差和的过程,最终把K个D维向量合起来后进行即得到最终输出的
K×D长度的一维向量。
而VLAD本身是不可微的,因为上面的a要么是0要么是1,表示要么当前描述x是当前聚类,要么不是,是个离散的,NetVLAD为了能够在深度卷积网络里使用反向传播进行训练,对a进行了修正。
那么问题就是如何重构一个a,**使其能够评估当前的这个x和各个聚类的关联程度?**用softmax来得到:
ak=eWk′Txi+bk′eWkTxi+bk
将这个把上面的a替换后,即是NetVLAD的公式,可以进行反向传播更新参数。
所以一共有三个可训练参数,上式a中的
c:K×D,而原始VLAD只有一个参数c。
最终池化得到的输出是一个恒定的K x D的一维向量(经过了L2正则),如果带Batchsize,输出即为Batchsize x (K x D)的二维矩阵。
NetVLAD作为池化层嵌入CNN网络即如下图所示,
原论文中采用将传统图像检索方法VLAD进行改进后应用在CNN的池化部分作为一种另类的局部特征池化,在场景检索上取得了很好的效果。
后续相继又提出了ActionVLAD、ghostVLAD等改进。
**评价:**这个NetVLAD Layer和SENet非常相似,可以看做是通道注意力机制的实现,不过具体实现方法有别于SENet。
Bilinear Pooling是在《Bilinear CNN Models for Fine-grained Visual Recognition》被提出的,主要用在细粒度分类网络中。双线性池化主要用于特征融合,对于同一个样本提取得到的特征x和特征y, 通过双线性池化来融合两个特征(外积),进而提高模型分类的能力。
主要思想是对于两个不同图像特征的处理方式上的不同。传统的,对于图像的不同特征,我们常用的方法是进行串联(连接),或者进行sum,或者max-pooling。论文的主要思想是,研究发现人类的大脑发现,人类的视觉处理主要有两个pathway, the ventral stream是进行物体识别的,the dorsal stream 是为了发现物体的位置。
论文基于这样的思想,希望能够将两个不同特征进行结合来共同发挥作用,提高细粒度图像的分类效果。论文希望两个特征能分别表示图像的位置和对图形进行识别。论文提出了一种Bilinear Model。
如果特征 x 和特征y来自两个特征提取器,则被称为多模双线性池化(MBP,Multimodal Bilinear Pooling)
如果特征 x = 特征 y,则被称为同源双线性池化(HBP,Homogeneous Bilinear Pooling)或者二阶池化(Second-order Pooling)。
pytorch实现: