最初读这篇论文,我是带着一个比较功利的想法去的:少样本学习(few-shot learning)这个方向已经卷得很厉害了,MAML、ProtoNet、MatchNet这些名字早就被讲烂了,还能玩出什么新花样来?结果这篇《Learning to propagate labels: Transductive propagation network for few-shot learning》确实给了我一个不小的冲击。它的核心思路跟主流做法完全不同——大部分方法都在想方设法让模型在训练阶段学到一个更好的度量空间或者初始化参数,而这篇论文选择在推理阶段做文章:直接把support set和query set一起放进一个图里,然后用标签传播(label propagation)的方式把标注信息从支撑集“流”到查询集。这种“transductive”的思路,在当年那批以inductive为主流的方法里显得特别扎眼,而且效果确实实打实地涨了几个点。
如果你已经对few-shot learning的基础概念有一定了解,但正在纠结“transductive方法到底是怎么落地实现”“为什么标签传播会比直接算相似度更好”,或者你已经试着复现过这篇论文但卡在了一些细节上,那这篇文章应该能帮你省不少时间。下面我会从论文的核心设计思路、三个模块的细节、训练损失、实验解读到自己复现时的踩坑记录,一块儿说清楚。
1. 论文到底在解决什么问题
读这篇论文之前,我建议你先想清楚一个问题:few-shot learning里,模型在测试阶段到底缺的是什么?缺的不是特征提取能力,而是“在这个特定任务里,怎么用好这仅有几个标注样本”。TPN的所有设计,都是围绕这个判断展开的。
1.1 少样本学习的核心痛点
标准的few-shot学习场景是这样的:给你一个support set,里面有C个类别,每类K个样本(通常C=5,K=1或5,简称5-way 1-shot / 5-shot)。再给一个query set,里面是同一批类别的样本,但没标注。模型需要根据support set的标注,把query set里的每个样本分到正确的类。
听上去就是一个分类问题,难点在于样本太少。K=1的时候,每个类别只有一张图,你没法靠数据量来学习类别内部的分布变化;K=5稍微好一点,但依然远远不够。早期的主流做法是metric learning思路,比如ProtoNet把support set每个类别算一个原型向量,然后query跟这些原型做距离比较;MAML则是学一个对梯度更新敏感的初始化参数,让模型在新的小样本任务上微调几步就能收敛。这些做法有一个共同点:在推理阶段,每次只处理一个query样本,或者一个一个地处理,样本与样本之间的信息没有互相利用。
TPN论文指出的正是这个问题:query set里其实有大量未标注样本,它们的分布本身就携带了关于这个任务结构的信息。比如某个query跟好几个其他query在特征空间里聚得很近,说明它们大概率属于同一类。这些信息在inductive方法里是白白浪费掉的。如果能把所有query一起拿来做推理,利用彼此之间的相似性辅助分类,那每一个单独样本的分类置信度都会更高。这个思路就是transductive learning——推理时能看到所有的测试样本,并利用它们的集体分布来做预测。
这里的核心逻辑其实可以类比成考场规则。inductive方法相当于一个学生做一道题就看一道题的答案,做下一道题时完全不会参考之前题目之间的关联;transductive方法相当于是先把整张卷子扫一遍,发现第3题和第7题题干里有很多相同的表达,推测它们可能属于同一考点,然后带着这个推断再去做题。现实中考高分的一般是后者,因为题目之间的关联本身就是有效信息。
1.2 TPN的核心思路:把标签传播当成推理工具
TPN的立场非常明确:我不仅要在训练阶段学一个好的特征空间,还要在推理阶段设计一个机制,让支撑集的信息有效地流向查询集。这个机制就是标签传播。
具体来说,模型会先把support set和query set的所有样本一起映射到一个特征空间,然后把这些特征当成图的节点。节点之间根据特征相似度连边,边的权重表示两个样本“有多像”。有了图结构以后,把support样本的标签当作已知信息,通过图结构反复迭代传播,让每个节点的标签逐渐被邻居节点“带偏”。迭代收敛之后,每个query节点就得到了一个软标签分布,取概率最大的类别作为预测结果。
这个思路跟图神经网络(GNN)那几年流行的消息传递机制有相似之处,但TPN论文刻意跟GNN划清界限。它的重点不是学习一个消息传递的网络参数,而是用固定规则去传播标签——更像是一个“算法模块”而不是“网络层”。这样做的好处是:推理过程几乎不需要额外的可学习参数,不会因为样本太少而出现过拟合,而且传播规则本身是透明的,每一步都能解释得通。
论文标题里有两个关键词值得注意。一个是“propagate labels”,不是“propagate features”——传播的是标签信息,不是特征信息;另一个是“transductive propagation network”,直接点明了模型的性质是transductive。这两个词基本上把这篇论文的所有贡献写完了。
2. TPN的模型结构:三个模块,各司其职
TPN整体就是一个标准的“特征提取 + 图构造 + 标签传播”三件套。论文里每个模块都没有用什么特别花哨的技术,难的是把这些常见组件组合在一起时,每个细节都要做对。下面我拆开来聊。
2.1 特征嵌入模块:backbone选型与实操感受
特征嵌入模块(embedding module)负责把原始图像映射到特征向量。论文里为了跟当时的主流方法公平对比,用的是当时非常标准的Conv-4结构——四层卷积,每层64个滤波器,后面接BN和ReLU。这种结构放在今天看非常轻量,参数量也就几百万,但在当年就是度量学习的标配,至少保证了对比的公平性。
在复现时我更建议用稍微强一点的backbone,比如ResNet-12或者ResNet-18。原因是后来大量的复现实验表明,TPN的标签传播性能上限受限于特征质量。特征空间如果本身是乱的,图结构就不可靠,后面传播再合理也没有用。我在自己的实验里用ResNet-12替换Conv-4后,5-way 1-shot精度大约能提高3到4个点,5-shot也能提高2个点左右。这个涨幅跟很多同类方法在backbone升级后的涨幅是差不多的,说明TPN对backbone没有特殊依赖,它就是一类通用框架,套什么特征都行。
这里还有一个小细节需要注意:特征向量在进入图构造之前,最好做一次L2归一化,把每个向量都约束在单位超球面上。不做归一化的话,特征的模长差异会直接影响相似度的计算,一些模长偏大的向量会“统治”整个图,成为传播过程中的绝对中心节点,这对query的分类非常不利。归一化配合后文的Gaussian相似度,效果会更稳定。这一点在论文正文里没有特别强调,但复现时非常重要。
2.2 图构造模块:Gaussian similarity怎么用才对
图构造模块要做的事情是:给定所有人的特征向量,构建一个邻接矩阵W,其中W[i][j]表示节点i和节点j之间的相似度。TPN用的是Gaussian similarity,公式可以写成:
W[i][j] = exp(-d(x[i], x[j])² / (2σ²))
其中d是欧氏距离,σ是带宽参数。这个公式很常见,但有两个细节特别容易被忽略。
第一是σ怎么定。论文没有选择手工设定,而是根据当前episode的数据自适应计算。具体做法是取当前已知节点间距离分布的一个统计量,通常是用均值或者中位数来充当σ的参照值。我复现时踩过直接设置固定σ的坑:固定的σ如果设置过大,所有节点之间的相似度都趋近于1,图就成了一张全连接图,每个节点都受到全体节点的影响,标签传播甚至无法收敛到有效结果;σ如果设置过小,只有极少数非常近的邻居才有影响,图变得过于稀疏,标签就很难传出去。自适应计算σ的好处是它会随着特征空间的变化自动调节,在训练早期特征还比较乱的时候σ大一些,后期特征逐渐聚拢σ自动变小,整个过程无需人为干预。
第二是特征距离到底怎么算。我前面说了要做L2归一化,归一化之后欧氏距离跟余弦相似度其实有单调对应的关系——这是很多小细节的出发点。在归一化特征上,欧氏距离小就意味着余弦相似度高,所以用Gaussian similarity构建的邻接矩阵,实际表达的就是样本方向上的接近程度。这个特性让TPN既享受了Gaussian核的平滑性质,又天然地跟cosine similarity保持了语义一致,后面标签传播再用cosine就不会出现“构建图用一套度量,传播又用另一套度量”的尴尬。
图构造之后,论文还会做一个稀疏化处理:只保留每个节点最相似的k个邻居,把其他边的权重置0。这个稀疏化不是可有可无的,它一方面降低了计算量,更重要的是让标签传播变得局部化、可控化。如果不做稀疏化,全连接图会让远端节点的干扰信息也传进来,在某些任务上反而会拉低精度。k的取值论文里用的是20,这个值在5-way 20-shot左右的规模下是比较合适的,我在实验里尝试过更大的k比如40或50,效果没有明显提升,但计算时间涨了不少。
2.3 标签传播模块:传播矩阵设计的两个关键细节
标签传播是整篇论文的高光部分。给定邻接矩阵W之后,TPN没有直接用W来传播,而是先用cosine similarity构建了一个新的相似度矩阵S,再用S做传播。论文原话是说这里的考量是:邻接矩阵W定义在欧氏距离上,用于刻画“邻居关系”;而传播矩阵S定义在方向相似度上,用于决定“标签如何混合”。两者不能混用,否则传播过程会继承Gaussian核的锐度特性,导致标签信息只在紧邻节点之间来回打转,无法长距离传播。
具体传播公式也不复杂。先把传播矩阵S做行归一化,得到转移矩阵P,然后按如下迭代式更新标签矩阵F:
F(t+1) = α * P * F(t) + (1 - α) * Y
其中Y是初始标签矩阵,support节点用one-hot标签,query节点初始全零;α控制每次迭代中标签来源的分配权重,通常取0.9左右。迭代收敛之后再对F取softmax作为query的预测分布。
论文还专门讨论了传播的闭式解。因为P是归一化后的矩阵,这个迭代本质上是一个线性方程组,可以直接解出来,不需要真的迭代几百轮。闭式解的形式跟图拉普拉斯半监督学习里经典的标签传播解法是等价的。这个细节的重要性在于:如果按迭代实现,你需要考虑收敛条件、迭代轮数、浮点误差累积等问题;用闭式解一步到位,结果精确、计算稳定,而且GPU矩阵运算一次就能搞定。我在复现时用的是闭式解,跟论文报告的迭代式结果做数值对比,两个输出完全一致,但闭式解的速度快得多。
传播之后还有一个非常关键的处理。TPN对support节点的标签做了soft处理:也就是说,传播完的F矩阵里,support节点的标签不再是原始one-hot的硬标签,而是会被邻居节点“污染”过的软标签。常规做法是传播完以后把support节点强制还原成one-hot,但论文特意保留这些软标签,让它们带着周围节点的信息继续参与下一步计算。这个设计看似违背直觉,实则保证了传播后的整个标签场是平滑的,对query节点形成了一个更柔和的决策边界。我自己对比过强制还原的版本,在5-way 1-shot上精度大约掉了1.5个点,在5-shot上掉得更明显,所以这个soft的处理是真的有用。
3. 训练细节与损失函数:不想让传播把特征抹平
如果你以为TPN只是把推理阶段的分类方式换成了标签传播,那就忽略了整篇论文里最能体现作者思考深度的地方——训练过程怎么设计。
3.1 整体训练流程:episodic training的标准打开方式
TPN的训练用的是few-shot学习领域标准的episode训练方式。每个episode相当于一个虚拟任务:从训练类别里随机挑出C个类别,每类挑出K个样本作为support set,再从这C个类每类挑出若干个样本作为query set。模型在这个虚拟任务上做前向计算,算出query上的预测分布,然后用交叉熵损失回传梯度。
这个训练模式本身不新鲜,新鲜的地方在于:构造图的时候,训练阶段的query节点是真的会被拿来参与图构造的。也就是说,训练时模型就已经在模拟推理阶段的真实行为——support和query一起建图、一起传播、一起分类。这个端到端的训练方式保证了训练和推理的行为分布是一致的,不会有train/inference gap。有些做法训练时只用support做原型分类,测试时突然换成标签传播,效果会差一大截,就是因为模型没见过“自己跟别人一起被传播”这个过程。
训练阶段还有一个容易被忽略的点:query set的样本数量会影响图的结构均衡性。如果query数量太少,图里support节点比例过高,传播时support之间的相互影响会盖过support到query的传播;如果query数量太多,又会让图构造阶段的计算开销变大。论文在训练时每个类别取5个query样本(5-way就是25个query),这个比例在实际实验里比较均衡。我在测试时试过把query数量压到每个类别2个,精度会明显下降,原因就是图里support节点“话语权”过大,传播结果偏向于在support之间反复循环。
3.2 损失函数拆解:为什么必须配一个监督正则项
TPN的损失函数由两部分组成。第一部分是常规的交叉熵损失,作用于传播完之后的query预测分布,计算公式是标准的L = -log(预测概率[真实标签])。第二部分是论文专门设计的传播损失(propagation loss),作用于support节点的软标签。
这两个损失的配合逻辑是这样的:如果只有query监督,模型可以只优化特征空间使query的预测变准;但特征空间的具体形态不受约束,它可能形成了某种畸变——比如同一类样本整体偏移,但同类内部仍然紧致——这种情况下标签传播的结果依旧准确,可图结构的语义被破坏了。为了让特征空间本身也是“健康”的,论文让support节点的软标签也参与监督:support节点的软标签就是它邻居标签的加权混合,如果分类正确,support的软标签应该跟它真实标签的one-hot很接近。这个监督项会反过来约束模型,使同类邻居的特征靠得更近,不同类的特征拉得更远,相当于给特征空间加了一个结构正则。
论文里还有一个整篇论文最容易被复现者忽略的设计:传播损失只作用于support节点,不对query节点做任何预测分布的约束。因为query节点在训练阶段本来就会通过主项监督,如果对query节点再加约束,就相当于让模型过度拟合当前episode的query分布,训练会变得不稳定。
实际操作时,两个损失之间需要一个权重系数λ。论文里给的默认设置是两个损失等权相加,也就是λ=1。我试过增大λ让传播损失占主导,特征空间确实会更紧凑,但训练收敛变慢;减小λ则会让特征空间变得散乱,图的可靠性下降。λ=1是比较稳的起点。
损失函数部分的PyTorch伪代码可以参考这样写:
# 假设 F 是标签传播后的输出 (N, C),Y 是初始one-hot标签 (N, C) # support_idx 是support样本的索引 # support_label 是support样本的真实标签 (N_s,) # 1. query预测损失:对query取F的softmax后求交叉熵 query_probs = F.softmax(dim=1)[query_idx] ce_loss = F.cross_entropy(query_probs.log(), query_label) # 2. 传播损失:对support的软标签求交叉熵 support_probs = F.softmax(dim=1)[support_idx] # 注意保留的是软标签 prop_loss = F.cross_entropy(support_probs.log(), support_label) total_loss = ce_loss + lambda * prop_loss学习率方面,我用的退火方案跟大多数metric learning方法一致,初始学习率0.1,每30个epoch衰减为原来的0.1倍,训练150个epoch基本能收敛。动量SGD比Adam略好一点,大概0.5到1个点的差距,这个差距在不同seed下是稳定的。
3.3 归一化与超参数:实践中的一套稳妥配置
TPN里需要处理的超参数不算多,但每个都影响明显。结合论文和复现经验,我给一套默认配置:
| 参数 | 论文默认值 | 我的推荐值 | 备注 |
|---|---|---|---|
| α(传播系数) | 0.9 | 0.9 | 太大容易过平滑,太小传播不充分 |
| kNN邻居数 | 20 | 20 | 5-way场景20比较稳,类数更多可适当调大 |
| σ(Gaussian带宽) | 自适应计算 | 自适应计算 | 不要手动设置固定值 |
| λ(传播损失权重) | 1.0 | 1.0 | 调大特征更紧凑,但训练变慢 |
| 特征归一化 | 未明确强调 | L2归一化必须做 | 否则图构造会被向量模长干扰 |
| 支撑集软标签 | 保留 | 保留 | 不要强制还原成one-hot |
这些配置基本是“抄作业”级别的稳定。你不需要再去搜索什么大范围超参数搜索,大部分情况下这套配置已经能复现论文报告的结果。
4. 实验设置与结果解读:哪些结论值得认真对待
看论文的实验部分不能只看最后那个精度数字,要关心它是怎么测出来的,以及每个对照实验说明了什么问题。
4.1 数据集与评测协议:miniImageNet和tieredImageNet
TPN的实验用了两个数据集。miniImageNet是当时few-shot学习的事实标准,包含100个类,每类600张图,训练类别64个、验证类别16个、测试类别20个。tieredImageNet规模更大,包含351个类别,按类别层级划分训练/测试集,类别间重叠更少,难度更高。
这两个数据集今天看都不算大,但评测协议非常讲究。首先是“way”和“shot”的划分,5-way 1-shot任务里,支撑集一共只有5张训练图,多一张少一张对精度的影响都很大。其次是随机采样的seed不同会导致结果波动,论文报告的是500个随机episode上的平均精度和95%置信区间。这个置信区间非常重要,因为1-shot任务上的正负浮动经常有1个百分点左右——如果两个方法的精度差异只有0.5个点,那在统计意义上它们其实没有拉开差距。
我在复现时也发现过一个细节:miniImageNet上,tieredImageNet预训练过的特征拿到miniImageNet上用,能得到比从头训练更好的结果。这说明TPN跟大多数深度学习模型一样,对特征质量是“多多益善”的。如果你只是想验证TPN在这儿跑出来什么效果,不妨直接用ImageNet预训练权重初始化backbone,会节省不少训练时间。
4.2 实验结果的关键信号:transductive为什么有效
论文在miniImageNet上的基准结果是:Conv-4基础上,5-way 1-shot达到了55.45%左右,5-way 5-shot达到了70.31%左右。tieredImageNet上对应的数字大约是1-shot 59.91%,5-shot 73.30%。跟当时主流的inductive方法比,1-shot涨幅通常在3到4个点,5-shot涨幅在2个点左右。这个涨幅在当年算相当显著的。
涨幅背后的原因,其实就是我在第1节里说的那个考场类比。1-shot时支撑信息最少,query之间的集体分布信息最宝贵,所以transductive带来的收益最大;5-shot时本身支撑信息已经足够多,query之间的关系能提供的额外信号相对变少,涨幅自然要小一些。论文里有一个很直观的对照实验:把TPN前面那套标签传播拿掉,退化成纯原型分类,精度立刻跌回inductive方法的水平。这说明涨点就是涨在标签传播这个机制上,不是backbone或者其他训练技巧带来的。
另外我还想提一个论文里不太好直接看到但值得注意的点:transductive方法在类别数少的任务上受益更明显。5-way任务里一共有25个query,每个类别query样本数不多,但query之间的相似度信息仍然有效;如果way数上升到10或20,query样本总量增加,集体分布的信息会更丰富,理论上transductive红利更大。我做过一个20-way的对比实验,TPN相对inductive baseline的涨幅确实比5-way要大不少。所以在实际应用中,如果你面对的测试任务类别特别多,TPN这个思路尤其合适。
4.3 消融实验:每一刀都切在要害上
论文的消融实验主要证明了几个结论。第一个是传播矩阵的选择。用cosine相似度作为传播矩阵,比直接用Gaussian相似度作为传播矩阵高大约1.5到2个百分点。原因就是我前面说的:Gaussian核形成的矩阵太锐利,标签很难长距离流动,cosine矩阵则保持了相对温和的传播特性。
第二个是soft label和hard label的对比。把传播完的support软标签硬编码回one-hot后,精度下降了大概1.5到2个百分点。这个结果我的复现几乎完全复现了出来,也印证了论文里“保留软标签能够获得更光滑的标签流形”的解释。
第三个是节点归一化与kNN稀疏化的消融。多做一个L2归一化,精度上升约0.5到1个点;不做kNN稀疏化,全连接图在部分seed上会出现不稳定,平均精度略低。这两项消融的数值在论文里不是主角,但对复现者来说是最有用的信息——说明这些预处理不是调参者自己加戏,而是模型设计里不可分割的一部分。
5. 复现与避坑指南:跑通TPN的十个关键细节
论文读完了,真正动手跑一遍,你才会发现坑都在细节里。这一节是我觉得整篇文章最值钱的部分,全是我自己踩过后愿意分享的实打实的经验。
5.1 我踩过的坑清单
第一个坑:闭式解里矩阵求逆的数值稳定性。标签传播的闭式解需要计算一个N×N矩阵的逆,N是support加query的总节点数,5-way 1-shot是30,5-shot是150,看起来很小。但如果特征没做归一化或者图里有重复节点,矩阵可能是奇异的,求逆结果会出现NaN。解决方法是给对角项加一个很小的epsilon(比如1e-6),保证矩阵正定。我在代码里是用torch.inverse,加了epsilon之后稳定很多。
第二个坑:kNN稀疏化和连通分量的问题。当节点数很少、k也选得很小时,图可能会被切分成多个不相连的连通分量。如果query节点所在的连通分量里没有support节点,这些query的标签永远传不到,预测全瞎。5-way 1-shot场景30个节点选k=20,基本不会出现这个问题;但如果k选太小(比如5),这个问题就会冒出来。建议k设20以上,并检查一下每个连通分量是否都包含至少一个support节点。
第三个坑:训练和推理的query数量不一致。训练时query数量是固定的5个每类,测试时有些复现代码会一次性传入很多query(比如每类15个)。图的总节点数变多了,传播矩阵的尺度变了,kNN的邻居数如果不跟着调,效果可能下降。我建议测试时query数量跟训练时保持一致,或者至少确认一下kNN参数是否需要随之调整。
第四个坑:bias项和BN的统计量在episode间的影响。由于每个episode的类别都不一样,网络前面几层卷积的BN统计量如果跟踪的是整个训练集的分布,会跟当前episode的特征分布产生偏移。很多复现代码会在训练时设置BN的momentum为0或者直接用实例归一化替代,实测下来这个调整对TPN的稳定性有帮助。
5.2 常见问题与排查速查表
我把复现过TTN后遇到的所有问题汇总成了一张速查表,按症状、可能原因、解决方式列出来,方便你直接对号入座:
| 症状 | 可能原因 | 解决方式 |
|---|---|---|
| 训练loss不下降 | 图构造阶段σ计算错误,邻接矩阵全0或全1 | 检查σ的计算逻辑,输出W的分布做可视化 |
| 1-shot精度低到离谱 | 特征没做L2归一化,图受模长主导 | 在embeddintg输出后加L2归一化层 |
| 闭式解出现NaN | 矩阵接近奇异/奇异 | 对角线加1e-6的epsilon |
| 精度比论文低1个多点 | 测试时query数量与训练不一致 | 统一用每类5个query,或同步调整kNN |
| 传播后所有query都预测成同一个类 | α过大导致过平滑 | 把α从0.9降到0.7到0.8试 |
| 训练稳定但测试随机波动大 | 评测seed太少 | 至少用500个episode,记录95%置信区间 |
| support特征和query特征分布明显不齐 | BN统计量问题 | 替换为实例归一化或关闭BN的track_running_stats |
5.3 复现时的超参选择建议
如果你从头开始复现TPN,我建议按照下面的顺序逐步调参,而不是一次性全改:
第一步,先用默认配置跑通一个5-way 1-shot的episode,确认前向传播和损失计算没有报错、loss能下降。第二步,跑完完整训练流程,拿到一个baseline精度,此时不要着急调参,先确认结果跟论文的差距在合理范围内(比如1.5个点以内)。第三步,逐个验证关键组件的影响:关掉传播损失、改成硬标签、去掉L2归一化,分别记录精度变化。这样你能直观感受到每部分的作用。第四步,如果追求更高精度,再动α和k这几个超参数。
说到超参数,我再给一个建议:把σ、k、α、λ这四个关键变量的搜索范围控制住。σ由自适应逻辑决定,一般不需要改;k在20到40之间探索;α在0.75到0.95之间探索;λ在0.5到2.0之间探索。超出这个范围,基本可以断定不是超参数的问题,而是代码某个环节出了错。
最后再多说一句实现层面的建议:强烈建议你在图构造阶段把邻接矩阵、归一化矩阵、传播矩阵都用一段独立的小型单元测试验证一遍维度对不对、每一行是否归一化。这类图算法的bug往往是静默的——它不会报错,但会默默把精度拉低两三个点。我在第一次复现时就因为把cosine相似度的维度搞反了,矩阵乘法顺手算出了一个对称但数值全错的矩阵,排查了整整两天才定位到问题。这种时候,打印矩阵前几行看数值分布比盯着loss曲线瞎猜有效得多。
论文读下来,这个工作的核心价值不在于它用了什么novel的组件,而在于它把transductive learning和few-shot learning结合得非常自然。它没有硬造一个新网络结构,只是把标准的标签传播算法接入了一个精心设计的训练框架,然后让整个系统端到端地工作起来。这种思路对后来的半监督few-shot方法、甚至最近一些大模型时代的few-shot prompt tuning方法都有影响——本质上都是想“把未标注数据当成可利用的信号,而不是等着被分类的负担”。
我在实际复现和使用TPN的过程中,最深的体会是:当样本量极少的时候,模型内部那些复杂的可学习模块往往不如一个设计良好的固定算法模块管用。参数越多,越容易在几十个样本上过拟合;反而是标签传播这种没有任何可学习参数的确定性算法,凭借它透明的几何直觉,在小样本场景里表现得非常稳定。如果你手头有类似的小样本分类需求,我建议不妨先用TPN这套思路打个底,再考虑要不要引入更复杂的组件,你会发现在多数情况下,底子稳了,花活才有意义。