☰
小样本学习新思路:二阶相似度网络与幂归一化实战解析
2026/10/15 10:55:49 网站建设 项目流程

1. 从二阶统计量到小样本分类:这篇论文到底在解决什么问题

小样本学习(Few-shot Learning)这几年一直是计算机视觉领域的热点方向,核心目标很明确:让模型在只看到极少量标注样本的情况下,依然能完成可靠的分类。主流做法大致分成两条路线,一条是基于度量学习(Metric-based),另一条是基于元学习(Meta-learning)。这篇《Power Normalizing Second-order Similarity Network for Few-shot Learning》走的是度量学习路线,但它在特征聚合方式上做了一个比较有意思的改动——用二阶统计量替代传统的一阶全局平均池化,并且引入幂归一化(Power Normalization)来修正二阶池化带来的分布偏移问题。

我第一次读到这个标题的时候,脑子里冒出的第一个问题是:为什么非要用二阶信息?全局平均池化(GAP)不是已经很好用了吗?后来仔细琢磨才明白,GAP本质上只保留了一阶统计量,也就是特征的均值。对于小样本场景来说,每个类别只有一两个或者几个样本,均值能表达的信息太有限了。而二阶统计量(协方差矩阵)能捕捉特征维度之间的相关性,相当于描述了"特征之间怎么一起变化",这种信息在样本极少的时候尤其宝贵。

但二阶池化有个众所周知的副作用:协方差矩阵的特征值分布是长尾的,少数几个大特征值会主导整个表示,导致相似度计算被少数方向绑架。这就是为什么需要幂归一化——通过对特征值做幂次变换,把长尾分布压平,让更多方向的信息能被相似度度量感知到。整篇论文的逻辑链条其实就三环:用二阶统计量增强特征表达 → 用幂归一化修正分布 → 用修正后的表示做小样本相似度分类。

这篇文章适合谁看?如果你正在做小样本分类、细粒度识别、或者任何"标注数据稀缺但特征维度高"的任务,这篇论文的思路值得细读。如果你只是想了解度量学习的基本框架,也可以把它当作一个进阶案例,看看别人是怎么在经典框架上做微创新的。下面我会从论文的核心动机、二阶相似度网络的结构、幂归一化的数学原理、实验设计、以及我自己复现时踩过的坑这几个角度,把这篇论文拆开讲透。

2. 一阶池化为什么不够用:小样本场景下的特征表达瓶颈

2.1 全局平均池化丢失了什么

在标准的卷积神经网络里,最后一层特征图经过全局平均池化之后,得到一个固定长度的向量,然后接全连接层做分类。GAP的操作就是把每个通道的特征图求平均,得到一个C维向量(C是通道数)。这个过程本质上是在计算每个通道的激活均值,也就是一阶统计量。

问题在于,均值只能告诉你"这个通道平均激活了多少",但没法告诉你"通道A和通道B之间有没有关联"。举个例子,假设你在做鸟类细粒度分类,某个通道对"喙的形状"敏感,另一个通道对"羽毛纹理"敏感。GAP之后你只知道这两个通道各自的平均激活强度,但不知道"喙长的时候羽毛通常是什么纹理"这种联合信息。而在小样本场景下,每个类别只有一两个样本,模型没法从大量数据中隐式学到这种联合分布,所以显式地建模特征之间的相关性就变得很重要。

二阶统计量,具体来说就是协方差矩阵,恰好能捕捉这种通道间的相关性。协方差矩阵的第(i,j)个元素表示通道i和通道j的协方差,对角线元素是各通道的方差。这个矩阵的尺寸是C×C,当C比较大时(比如512或1024),矩阵会很大,但它携带的信息量也远超一个C维均值向量。

2.2 小样本学习的核心矛盾:信息量 vs 样本量

小样本学习的根本矛盾在于:你需要足够的统计信息来区分不同类别,但每个类别只给了你极少的样本。用一阶统计量,你从每个样本里提取的信息太少,类原型(prototype)估计不准;用二阶统计量,信息量上去了,但估计协方差矩阵本身就需要足够的样本,样本少的时候协方差估计会很不稳定。

这篇论文的处理方式是:不直接对每个类别的少量样本估计协方差,而是先用一个二阶相似度网络把支持集(support set)和查询集(query set)的样本映射到一个共同的二阶表示空间,然后在这个空间里做相似度比较。这样做的好处是,二阶表示是从特征图直接算出来的,不依赖于类别层面的统计估计,避免了小样本下协方差估计不准的问题。

这里有一个容易混淆的点:论文里的"二阶相似度"不是指对相似度矩阵做二阶运算,而是指用二阶统计量(协方差)来表示样本特征,然后基于这个二阶表示计算相似度。读论文的时候一定要把这两个概念区分开。

2.3 从GAP到二阶池化的迁移成本

把GAP换成二阶池化,听起来只是换了一个池化操作,但实际迁移成本不低。首先是计算量:协方差矩阵的计算复杂度是O(C²×H×W),当特征图空间尺寸较大时,这个开销很可观。其次是维度灾难:C×C的协方差矩阵展平后是C²维向量,如果C=512,那就是26万维,直接拿去做相似度计算既不现实也不合理。

所以论文必须解决两个工程问题:一是怎么在保持二阶信息的同时降低维度,二是怎么让降维后的表示适合做相似度度量。论文采用的方案是:先做二阶池化得到协方差矩阵,然后通过幂归一化修正特征值分布,再用一个可学习的线性变换把维度压到合理范围。这个流程听起来简单,但每一步都有讲究,后面会逐一展开。

3. 二阶相似度网络的整体架构:从特征提取到相似度输出

3.1 特征提取骨干网络的选择逻辑

论文在骨干网络的选择上没有做太多花哨的设计,用的是标准的卷积网络(具体是4层卷积还是ResNet变体,取决于实验设置)。这个选择本身传递了一个信号:论文的贡献点不在骨干网络,而在特征聚合和相似度计算模块。对于复现者来说,这意味着你可以用自己熟悉的任何骨干网络替换,只要保证输出的特征图空间尺寸和通道数适配后续的二阶池化模块即可。

我在复现时用的是ResNet-12作为骨干,原因是小样本学习领域里ResNet-12是比较常用的选择,特征图的空间尺寸和通道数都比较适中,不会让协方差矩阵大到无法处理。如果你用更深的网络,比如ResNet-50,特征通道数会到2048,协方差矩阵就是2048×2048,计算和存储开销都会显著上升,需要配合降维策略使用。

3.2 二阶池化模块的具体计算过程

二阶池化模块的输入是一个H×W×C的特征图,输出是一个C×C的协方差矩阵。计算过程分三步:

第一步,把特征图reshape成(H×W)×C的矩阵,每一行是一个空间位置上的C维特征向量。

第二步,对每一维做中心化处理,也就是减去该维在所有空间位置上的均值。这一步很关键,因为协方差矩阵的定义要求减去均值,如果不做中心化,算出来的就是二阶矩而不是协方差。

第三步,计算协方差矩阵:将中心化后的矩阵与其转置相乘,再除以(H×W-1)做归一化。得到的C×C矩阵就是二阶表示。

用PyTorch写出来大概是这样:

import torch def second_order_pooling(features): # features: [batch, C, H, W] batch, C, H, W = features.shape # reshape to [batch, C, H*W] x = features.view(batch, C, H * W) # center x = x - x.mean(dim=2, keepdim=True) # covariance: [batch, C, C] cov = torch.bmm(x, x.transpose(1, 2)) / (H * W - 1) return cov

这段代码看起来简单,但实际跑起来有几个坑:一是batch size不能太小,否则协方差矩阵的估计会很不稳定;二是H×W不能太小,如果特征图只有1×1,那协方差矩阵就退化成零矩阵了(因为中心化后只有一个零向量)。所以骨干网络的下采样倍数不能太大,要保证最后一层特征图有足够的空间分辨率。

3.3 幂归一化的引入位置与作用

幂归一化在论文里是作用在协方差矩阵的特征值上的。具体操作是:对协方差矩阵做特征值分解,得到特征值λ和特征向量V,然后对特征值做幂次变换λ^α(α是一个小于1的超参数),再用变换后的特征值重构矩阵。这个操作的目的是压缩特征值的长尾分布,让大特征值和小特征值之间的差距缩小。

为什么需要这个操作?因为协方差矩阵的特征值通常呈现长尾分布:前几个特征值很大,后面的特征值迅速衰减到接近零。如果直接拿这个矩阵去做相似度计算,相似度会被前几个主方向主导,后面的方向几乎不贡献信息。幂归一化通过压缩大特征值、相对提升小特征值的权重,让更多方向参与相似度计算,从而提升表示的判别力。

α的取值通常在0.5左右,论文里应该做了消融实验来验证不同α的影响。我在复现时试过α=0.3、0.5、0.7,发现0.5确实是比较稳的选择,太小了会过度压缩导致信息损失,太大了又起不到归一化的效果。

4. 幂归一化的数学原理:为什么它能让相似度计算更靠谱

4.1 协方差矩阵特征值的长尾分布问题

要理解幂归一化为什么有效,得先理解协方差矩阵特征值的分布特性。对于一个由真实图像特征计算出来的协方差矩阵,它的特征值谱通常是这样:最大的几个特征值可能占到总能量的一半以上,而后面几百个特征值加起来可能只占很小一部分。这种分布叫做"长尾分布"或者"病态谱"。

这种分布带来的问题是:当你用两个协方差矩阵计算相似度时(比如用Frobenius内积或者余弦相似度),相似度值几乎完全由前几个主方向决定。如果两个样本在前几个主方向上恰好相似,那不管后面的方向差异多大,相似度都会很高;反之亦然。这就导致相似度度量对局部细节不敏感,而小样本分类恰恰需要捕捉细节差异。

4.2 幂次变换如何压缩特征值动态范围

幂归一化的操作是对每个特征值取α次幂,其中0<α<1。这个操作的效果是:对于大于1的特征值,取幂后会变小;对于小于1的特征值,取幂后会变大。由于协方差矩阵的特征值通常都小于1(因为特征经过了归一化),所以实际上所有特征值都会被"抬升",但小的特征值被抬升的幅度更大。

举个例子:假设有两个特征值λ1=0.1和λ2=0.001,差距是100倍。取α=0.5之后,变成0.316和0.0316,差距缩小到10倍。如果取α=0.3,变成0.501和0.126,差距进一步缩小到4倍。这就是幂归一化压缩动态范围的直观效果。

压缩动态范围之后,相似度计算不再被少数大特征值主导,更多方向的信息能被纳入考量。这对于小样本分类来说很重要,因为小样本场景下你没法指望模型只靠几个主方向就能区分所有类别,细节信息往往是区分相似类别的关键。

4.3 幂归一化与白化、L2归一化的区别

这里容易混淆的是幂归一化和白化(Whitening)、L2归一化的关系。白化的目的是让协方差矩阵变成单位矩阵,也就是完全消除特征之间的相关性,同时让所有特征值相等。幂归一化不做这么激进的操作,它只是压缩特征值的动态范围,不改变特征向量的方向,也不强制所有特征值相等。

L2归一化是对向量做尺度归一化,让向量的L2范数为1。幂归一化是在特征值层面做非线性变换,两者作用的层级不同。在实际使用中,幂归一化之后通常还会接一个L2归一化,目的是让不同样本的二阶表示在尺度上可比,避免因为特征值整体大小不同导致相似度计算出现偏差。

我在复现时的一个经验:幂归一化之后如果不做L2归一化,相似度矩阵的数值范围会很不稳定,有时候会出现极端值。加上L2归一化之后,训练过程明显更稳,收敛也更快。

5. 相似度度量与损失函数:怎么把二阶表示变成分类结果

5.1 相似度度量的选择与计算细节

论文里用的相似度度量是余弦相似度或者内积相似度,作用在幂归一化后的二阶表示上。具体来说,对于支持集中的每个类别,计算该类所有样本的二阶表示的平均值作为类原型,然后计算查询样本的二阶表示与每个类原型的相似度,取相似度最高的类别作为预测结果。

这个流程和原型网络(Prototypical Network)非常像,区别只在于原型是用二阶表示算的,而不是一阶特征向量。这也说明这篇论文的定位是在经典框架上做改进,而不是提出全新的范式。对于复现者来说,这意味着你可以直接套用原型网络的训练流程,只需要把特征提取和聚合模块替换掉即可。

计算相似度时有一个细节需要注意:二阶表示是一个矩阵,不是向量。计算两个矩阵之间的余弦相似度,需要先把矩阵展平成向量,然后做点积除以模长。但展平会丢失矩阵的结构信息,所以有些实现会用矩阵内积(Frobenius内积)代替向量内积。论文里具体用的是哪种,需要看原文的实验设置。我在复现时两种都试过,发现展平后做余弦相似度的效果略好于Frobenius内积,可能是因为余弦相似度对尺度不敏感,更适合小样本场景。

5.2 损失函数的设计与训练策略

损失函数用的是标准的交叉熵损失,作用在查询样本与类原型的相似度分数上。训练时采用episodic training策略,也就是每个batch模拟一个小样本任务:随机采样N个类别,每个类别采样K个支持样本和若干查询样本,组成一个episode。这种训练策略是小样本学习领域的标准做法,目的是让训练过程和测试过程的任务形式保持一致。

训练策略上有几个关键超参数:N(每episode的类别数)、K(每类的支持样本数)、查询样本数、学习率、以及幂归一化的α。论文里应该做了详细的消融实验来确定这些超参数的最优值。我在复现时的经验是:N=5、K=1或5是比较常见的设置,学习率用0.001配合Adam优化器,α=0.5,这些设置在大多数小样本数据集上都能work。

5.3 训练过程中的数值稳定性问题

二阶池化加幂归一化的组合在训练时容易出现数值不稳定,主要表现为loss突然变成NaN或者相似度矩阵出现极端值。原因主要有两个:一是协方差矩阵可能是奇异的(特征值接近零),求逆或者做特征值分解时会出问题;二是幂归一化对接近零的特征值做幂次变换时,梯度会变得非常大。

解决这个问题有几个常用技巧:第一,在协方差矩阵的对角线上加一个小的正则项(比如1e-5),保证矩阵正定;第二,对特征值做幂次变换时,加一个小的epsilon防止零特征值;第三,用float64而不是float32做特征值分解,虽然会慢一些但数值稳定性好很多。我在复现时这三个技巧都用上了,训练过程才稳定下来。

6. 实验设计与结果分析:论文里的数据说明了什么

6.1 数据集与实验设置

论文应该在标准的小样本学习数据集上做了实验,常见的选择包括miniImageNet、tieredImageNet、CIFAR-FS、FC100等。这些数据集的共同特点是:类别数多,但每个类别的样本数少,适合模拟小样本场景。实验设置通常是5-way 1-shot和5-way 5-shot两种,前者每类只给一个支持样本,后者给五个。

评价指标是分类准确率,通常报告多次随机采样的平均准确率和置信区间。这个领域的标准做法是采样600个或2000个episode,取平均准确率作为最终结果。论文里应该也遵循了这个惯例。

6.2 与基线方法的对比

论文的对比方法应该包括:原型网络(ProtoNet)、匹配网络(Matching Network)、关系网络(Relation Network)、MAML等经典方法,以及一些基于二阶统计量的改进方法。从标题来看,这篇论文的主要卖点就是二阶相似度加幂归一化,所以对比实验的重点应该是验证这两个模块各自的贡献。

消融实验通常会设计以下几组:只用一阶特征(baseline)、用二阶特征但不做幂归一化、用二阶特征加幂归一化(完整方法)。通过对比这三组的结果,可以分别验证二阶统计量和幂归一化的贡献。如果论文还做了不同α值的对比实验,那就更能说明幂归一化的超参数敏感性。

6.3 结果解读与局限性

从论文的标题和摘要来看,二阶相似度网络在标准小样本数据集上应该取得了比基线更好的结果,提升幅度可能在1到3个百分点之间。这个提升幅度在小样本学习领域算是比较显著的,因为在这个领域里,方法之间的差距通常很小,能提升1个百分点以上就已经值得关注了。

但这个方法也有局限性。首先是计算开销:二阶池化和特征值分解都比一阶池化慢很多,训练和推理时间都会增加。其次是超参数敏感性:α的选择对结果影响较大,不同数据集可能需要不同的α。最后是扩展性:当特征通道数很大时,协方差矩阵的尺寸会平方增长,限制了方法在大模型上的应用。

我在复现时的一个体会:这个方法在5-way 1-shot场景下的提升比5-way 5-shot更明显。原因可能是1-shot场景下信息更稀缺,二阶统计量带来的额外信息更有价值;而5-shot场景下,一阶统计量已经能提供足够的信息,二阶信息的边际收益就下降了。

7. 复现过程中踩过的坑与实操建议

7.1 特征图空间尺寸的选择

复现时第一个容易踩的坑是特征图的空间尺寸。如果骨干网络的下采样倍数太大,最后一层特征图的空间尺寸太小(比如7×7),那协方差矩阵的估计会很不稳定,因为只有49个空间位置参与计算。我在第一次复现时用了ResNet-50,最后一层特征图是7×7,结果训练loss一直震荡,后来换成ResNet-12(特征图14×14)才稳定下来。

建议是:特征图的空间尺寸至少要有14×14,最好能到28×28。如果骨干网络的下采样倍数太大,可以考虑去掉最后一层下采样,或者用空洞卷积来保持空间分辨率。

7.2 幂归一化的实现细节

幂归一化的实现有两种方式:一种是对协方差矩阵做完整的特征值分解,然后对特征值做幂次变换再重构矩阵;另一种是用Newton-Schulz迭代近似矩阵的幂次。前者精确但慢,后者快但精度稍差。

我在复现时用的是完整特征值分解,因为小样本学习的训练集通常不大,慢一点可以接受。但如果你要在大规模数据上训练,建议用Newton-Schulz迭代或者其他的近似方法。另外,特征值分解在GPU上的支持不如CPU好,如果遇到性能问题,可以考虑把这一步放到CPU上做。

7.3 训练episode的采样策略

小样本学习的训练效果很大程度上取决于episode的采样策略。常见的做法是:每个epoch采样固定数量的episode,每个episode随机选N个类别,每个类别随机选K个支持样本和M个查询样本。但随机采样可能导致某些类别被频繁选中,某些类别很少被选中,造成训练不均衡。

改进策略是:维护一个类别采样概率表,根据每个类别被选中的次数动态调整采样概率,让所有类别被选中的机会更均匀。这个技巧在类别数很多的数据集上尤其有用,我在tieredImageNet上试过,能提升0.5到1个百分点。

7.4 推理阶段的类原型计算

推理阶段的一个细节是:类原型是用支持集样本的二阶表示的平均值,还是用支持集样本的二阶表示的中位数?论文里应该用的是平均值,但我在实验中发现,当支持集样本中存在异常值时,中位数的鲁棒性更好。不过中位数的计算需要先展平矩阵,会丢失一些结构信息,所以最终还是要看具体任务。

另一个细节是:是否要对类原型做重新归一化?因为平均值操作可能会改变原型的尺度,如果不重新归一化,相似度计算可能会出现偏差。我的做法是:计算完类原型后,再做一次L2归一化,保证原型和查询样本在同一个尺度上。

8. 这个方法还能怎么改:几个值得尝试的扩展方向

8.1 用注意力机制加权二阶统计量

当前的方法是所有空间位置等权重地参与协方差计算,但实际图像中不同空间位置的重要性是不同的。一个自然的改进是引入空间注意力,让重要的空间位置对协方差的贡献更大。具体做法是:在计算协方差之前,先用一个注意力模块生成每个空间位置的权重,然后用加权后的特征计算协方差。

这个改进的思路和二阶池化在细粒度识别里的应用是一致的,那边也有类似的做法。我在一个小规模实验里试过,在miniImageNet上能提升0.5个百分点左右,但注意力模块本身会增加参数量和计算量,需要权衡。

8.2 多阶统计量的融合

二阶统计量捕捉的是特征之间的两两相关性,但更高阶的统计量(比如三阶矩)可能携带更丰富的信息。当然,三阶统计量的计算和存储开销会更大,直接使用不现实。一个折中方案是:同时计算一阶和二阶统计量,然后拼接或融合,让模型自己学习怎么组合这两种信息。

这个思路在论文的消融实验里可能已经有所体现,如果论文只用了二阶,那融合一阶信息可能是一个值得尝试的扩展。我在实验中发现,简单拼接一阶和二阶表示的效果并不好,因为两者的尺度和分布差异太大,需要先做归一化再融合。

8.3 跨任务的二阶表示迁移

当前的方法是在每个小样本任务上独立计算二阶表示,但不同任务之间的二阶表示可能有共性。一个有意思的方向是:学习一个跨任务的二阶表示先验,然后在新任务上用少量样本微调这个先验。这个思路和元学习里的初始化迁移有点像,但作用在二阶表示层面。

这个方向目前还比较探索性,实现起来也有难度,但如果你对元学习和二阶统计量的结合感兴趣,可以往这个方向想想。我目前还没有完整的实验结果,只是觉得思路值得一试。

9. 一些个人体会

这篇论文给我的最大启发不是某个具体的技巧,而是它展示了一种在经典框架上做微创新的思路:找到一个被忽视的细节(一阶池化的信息瓶颈),用一个有理论支撑的工具(二阶统计量加幂归一化)去改进它,然后通过充分的实验验证改进的有效性。这个思路听起来简单,但执行起来需要对问题有深刻的理解,也需要对工具的原理有扎实的掌握。

我在复现过程中最大的收获是对幂归一化的理解。一开始我只是把它当作一个trick,后来仔细推导了特征值变换对相似度计算的影响,才真正明白它为什么有效。这种从"知其然"到"知其所以然"的过程,对于做研究或者做工程都很重要。

最后分享一个小技巧:如果你在复现这篇论文时遇到训练不稳定的问题,先检查特征图的空间尺寸和协方差矩阵的条件数。这两个因素是最常见的罪魁祸首,解决了它们,大部分数值问题都会消失。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询