归纳推理任务要求模型从有限的样例中总结出潜在规律,再将规律应用到新输入上,典型场景包括少样本函数学习、序列规律推断和图结构类比。训练中经常出现一个尴尬现象:模型在见过的样例上几乎完美,一旦换成规则相同但表面形式不同的新样例,准确率就断崖式下跌。这并非模型容量不够,而是模型选择了更省力的路径,直接记忆输入到输出的映射,绕过了对规律本身的抽象。多样性正则化正是针对这一问题设计的约束手段,它通过惩罚过于单一的表示,迫使模型关注规律的多样表达形式。

为什么归纳推理模型容易死记硬背
从优化角度看,记忆远比抽象便宜。以一个“找规律填数”任务为例,训练集里每个谜题都是独立的输入输出对,如果模型参数量足够大,它完全可以为每个谜题分配一组专用参数,把答案硬编码进去,这样训练损失下降得又快又稳。相比之下,先归纳出“等差数列”“交替运算”这类抽象规则,再套用到具体数字上,需要模型跨越不同表面形式提取共性,优化路径更曲折。
另一个推手是数据分布的狭窄性。如果训练样例中某个规则总是伴随特定表面特征出现,比如“平方规律”的谜题总是用两位数出题,模型就会把“两位数”当成预测线索。一旦测试样例把平方规律套在三位数上,模型立刻失效。这种伪相关是归纳推理过拟合的最常见形态,学到的不是规则而是规则与表面特征的绑定。
判断模型是否在死记硬背,有一个简单实验:把同一批谜题的数字随机替换成同分布的新数字,保持规则不变。泛化良好的模型准确率应基本不变;如果准确率大幅下滑,说明模型记忆的是具体数字而非规则本身,此时引入正则化手段就非常必要。
多样性正则化的核心思想与实现
多样性正则化的目标可以用一句话概括:让模型在不同输入上学到的内部表示保持足够的差异,同时让同类输入的表示保持一致。这听起来有些矛盾,但仔细想想,归纳推理的规律恰恰体现在“同规则不同形式”的样例之间。如果所有样例的中间表示都挤在一个狭窄区域,模型就失去了区分不同规律的机会,退化为查表器。
最常见的做法是在损失函数中加入一个基于表示分布的约束项。比如对模型输出的规则分布施加熵正则:若模型对所有训练样例都倾向于输出同一个“万能规则”的峰值分布,熵惩罚会推高分布的平坦度,迫使它在不同规则之间做出真实区分。下面是一个结合熵正则的训练片段:
import torch
import torch.nn.functional as F
def loss_with_entropy_reg(model, inputs, targets, beta=0.05):
logits, reprs = model(inputs)
# 主任务损失:规则预测的交叉熵
task_loss = F.cross_entropy(logits, targets)
# 对预测分布求平均后计算熵,惩罚过度集中的平均分布
avg_prob = logits.softmax(dim=1).mean(dim=0)
entropy = -(avg_prob * torch.log(avg_prob + 1e-8)).sum()
# 注意符号:我们希望平均分布的熵适中,这里以最小化负熵的方式约束
return task_loss - beta * entropy, reprs
代码中的beta控制约束强度,取值过大会让模型输出趋于均匀,反而丧失判别力,一般从0.01到0.1之间网格搜索。除了熵正则,基于批内表示的协方差正则也很流行:计算一个batch内所有样例表示的相关矩阵,惩罚非对角元素过大,等价于鼓励表示向各维度正交,避免所有样例映射到同一个方向。
借助数据增强和对比学习放大多样性
正则化不只作用在损失函数上,也可以作用在数据层面。对归纳推理任务,最有效的增强是“规则保持变换”:替换数字、打乱谜题呈现顺序、改变符号系统,只要变换前后规则不变,就得到了一对天然的正样本。模型被要求对这类样本给出一致的输出,对规则不同的样本给出可区分的输出,这正是对比学习的框架。
这种做法的巧妙之处在于,它把“不要记数字”这一约束显式编码进了训练目标。模型若想满足一致性要求,唯一出路是学会对表面形式不变的量,也就是规则本身,做出响应。一个简单的对比损失实现如下:
def contrastive_loss(repr_a, repr_b, neg_reps, temperature=0.1):
# repr_a 与 repr_b 是同一谜题经规则保持变换后的两次表示
a = F.normalize(repr_a, dim=-1)
b = F.normalize(repr_b, dim=-1)
pos = (a * b).sum(dim=-1) / temperature
# neg_reps 是同批其他样例的表示,规则不同,应当被推开
neg = torch.mm(a, F.normalize(neg_reps, dim=-1).t()) / temperature
logits = torch.cat([pos.unsqueeze(1), neg], dim=1)
labels = torch.zeros(len(pos), dtype=torch.long, device=pos.device)
return F.cross_entropy(logits, labels)
三种手段各有侧重:熵正则实现简单,适合快速验证;协方差正则对表示几何的约束更直接;对比学习配合数据增强效果通常最好,但需要精心设计变换规则,且负样本质量对结果影响较大。实践中三者并非互斥,常见组合是“规则保持增强加上温和的熵正则”,先在验证集上确认变换后的样例确实保持原规则,再逐步加大正则权重。
落地时的调参经验与常见坑
第一个坑是正则强度过大导致欠拟合。多样性的本意是防止表示坍缩,但约束过强会让模型连真正该记住的判别信息也丢弃,表现为训练损失迟迟降不下去。建议的做法是把正则项系数设为可随训练进程变化的量:前期较小让模型先学会基础任务,后期逐渐加大压力逼出泛化能力,类似课程学习的思路。
第二个坑是增强规则本身引入泄漏或破坏规则。例如在图类比任务里随机重排节点编号是安全变换,但随机删边可能改变题目含义。每一类变换都应经过单元式的规则校验,确保变换前后的标准答案一致,否则模型学到的是被污染的对应关系,比过拟合更难排查。
最后建议建立两套评估:一套用原分布测试集,一套专门构造“表面形式变化但规则不变”的抗记忆测试集。后者才是衡量归纳能力的关键指标。多数实验中,引入多样性正则化后,原测试集准确率可能持平或略有下降,但抗记忆测试集提升明显,这正是我们期望的交换:用一点训练性能换取真正的规律抽象能力。