Hypernetworks
超网络是一种神经网络,可根据任务嵌入等输入生成另一个网络的权重。内容涵盖用途和 PyTorch 示例。
超网络是一种神经网络,其输出是另一个网络(称为目标网络或主网络)的权重。目标网络接收的不是一组固定的模型权重,而是由超网络根据任务标识、用户档案、文本描述或示例图像等条件输入计算出的权重。因此,只需一次前向传播,一个训练好的超网络就能针对每个输入生成不同的专用模型。Google Brain 于 2016 年发表的 HyperNetworks 论文中,David Ha、Andrew Dai 和 Quoc Le 使用小型超网络生成深度卷积网络和循环网络的权重;如今,这一思路已应用于持续学习、扩散模型个性化以及神经架构搜索。
超网络的工作原理#
训练过程中,只学习超网络自身的参数。条件输入(通常是每个任务或层的学习型嵌入)通过超网络生成目标网络的权重;目标网络使用这些权重处理实际数据,而反向传播则将损失梯度通过生成的权重传回超网络:
Ha 等人区分了静态超网络和动态超网络:静态超网络根据层嵌入一次生成每层的权重;动态超网络则像他们提出的 HyperLSTM 一样,在每个输入或时间步重新计算权重。运行时,生成的权重是普通张量,因此目标网络可以采用任何架构,包括由超网络生成注意力投影的 Transformer层。主要的工程难题是输出规模:一个包含数百万权重的层,需要超网络为该层输出数百万个值。实用设计会将权重分块,并为每块使用独立嵌入;或者只生成每个权重更新的小型低秩因子;也可以像特征级线性调制 (FiLM)那样,只生成逐通道的缩放和平移参数。
PyTorch 超网络示例#
这个 PyTorch 示例在一系列任务上训练超网络,这些任务是振幅和相位各不相同的正弦波。对于每个任务,超网络都会生成一个小型目标网络的全部 97 个权重,训练过程中只更新超网络:
import math
import torch
from torch import nn
torch.manual_seed(0)
x = torch.linspace(-math.pi, math.pi, 64)
# Hypernetwork: maps a task (amplitude, phase) to all 97 weights of a 1-32-1 target network
hyper = nn.Sequential(nn.Linear(2, 128), nn.ReLU(), nn.Linear(128, 97))
optimizer = torch.optim.Adam(hyper.parameters(), lr=1e-3)
def target(x, w):
"""Run the target network with weights w produced by the hypernetwork."""
return torch.relu(x[:, None] * w[:32] + w[32:64]) @ w[64:96] + w[96]
# Train only the hypernetwork, on a new random sine task at every step
for step in range(5000):
task = torch.rand(2) * torch.tensor([2.0, math.pi])
loss = ((target(x, hyper(task)) - task[0] * torch.sin(x + task[1])) ** 2).mean()
optimizer.zero_grad()
loss.backward()
optimizer.step()
# Unseen task: one forward pass of the hypernetwork produces the target network's weights
y = 1.5 * torch.sin(x + 1.0)
with torch.no_grad():
mse = ((target(x, hyper(torch.tensor([1.5, 1.0]))) - y) ** 2).mean()
print(f"Unseen task MSE: {mse:.3f} with generated weights, {(y**2).mean():.3f} predicting zero")它会输出 Unseen task MSE: 0.010 with generated weights, 1.132 predicting zero。振幅为 1.5、相位为 1.0 的目标网络从未参与训练;它的权重来自一次超网络调用,而超网络学会了如何在整个任务系列中调整合适的权重。
应用场景#
- 持续学习:以任务为条件的超网络会为每个任务存储一个小型嵌入,并按需重新生成该任务的权重。在新任务上训练时,会加入一项惩罚,确保超网络对早期任务嵌入的输出保持不变,从而遏制灾难性遗忘。
- 生成模型个性化:HyperDreamBooth 根据一张人脸照片,为文生图扩散模型预测一小组个性化权重,然后对这些权重进行短暂微调;整个模型个性化过程约需 20 秒,比 DreamBooth 快 25 倍,个性化权重也比 DreamBooth 模型小 10,000 倍。
- 神经架构搜索:图超网络会将候选架构作为图读取并预测其权重,因此可以根据预测权重下的验证准确率对候选架构排序,而不必逐个训练。
- 零样本分类:CLIP 的作者将其文本编码器描述为一个超网络,它能根据类别名称生成线性分类器的权重,使 CLIP 可以将图像分类到从未作为训练标签出现过的类别中。
开放词汇检测器将同一思路应用于目标检测。Ultralytics YOLOE-26 基于 YOLO26 构建,会使用 MobileCLIP2(一种轻量级的 CLIP 风格文本编码器)对传入 set_classes() 的每个类别名称编码一次,并将生成的嵌入作为权重,用于计算每个候选区域与每个类别的匹配分数。导出时,这些嵌入会折叠到检测头中的普通 1x1 卷积里。
超网络与相关术语#
- 微调:通过在新任务的数据上执行梯度更新,将一组固定权重适配到新任务。训练好的超网络只需接收任务的条件输入,就能通过一次前向传播生成新任务的权重。
- 元学习:学习快速适配新任务这一更广泛的目标。超网络是实现元学习的一种方式,能够将任务描述或少量示例直接映射为权重。
- 专家混合 (MoE):将每个输入路由到多个固定专家子网络中的少数几个。超网络会为每个输入或任务计算新的权重,而不是从已存储的权重中进行选择。
- 快速权重编程器:在处理序列的过程中,为另一个网络写入短期权重的网络。这一思路出现于 20 世纪 90 年代初。Transformer 中线性化的自注意力在形式上等价于这样的快速权重编程器。










