bilinear pooling主要用于特征融合,对于从同一个样本提取出来的特征x和特征y,通过bilinear pooling得到两个特征融合后的向量,进而用来分类。
如果特征x和特征y来自两个特征提取器,则被称为多模双线性池化(MBP,Multimodal Bilinear Pooling)
如果特征x=特征y,则被称为同源双线性池化(HBP,Homogeneous Bilinear Pooling)或者二阶池化(Second-order Pooling)
bilinear pooling详解:
bilinear pooling,就是先把两个特征(T为通道数) 双线性融合(相乘)后,得到矩阵b,对所有位置的b进行sum pooling(也可以是max pooling,但一般采用sum pooling以方便进行矩阵运算)得到矩阵ξ,最后把矩阵ξ 张成一个向量,记为bilinear vector (x) 。对x进行矩归一化操作和L2归一化操作后,就得到融合后的特征z 。
def bilinear_pooling(x,y):
x_size = x.size()
y_size = y.size()
assert(x_size[:-1] == y_size[:-1])
out_size = list(x_size)
out_size[-1] = x_size[-1]*y_size[-1] # 特征x和特征y维数之积
x = x.view([-1,x_size[-1]]) # [N*C,F]
y = y.view([-1,y_size[-1]])
out_stack = []
for i in range(x.size()[0]):
out_stack.append(torch.ger(x[i],y[i])) #torch.ger()向量的外积操作
out = torch.stack(out_stack) # 将list堆叠成tensor
return out.view(out_size) #[N,C,F*F]
原始的Bilinear Pooling存在融合后的特征维数过高的问题,融合后的特征维数=特征x和特征y的维数之积。原作者尝试了PCA降维,但效果并不理想。基于降低bilinear pooling特征维数的思想,提出CBP。
CBP: Compact Bilinear Pooling详解