原型库:AI 的“概念词典“
📚 《从零到一造大脑:AI架构入门之旅》专栏
专栏定位:面向中学生、大学生和 AI 初学者的科普专栏,用大白话和生活化比喻带你从零理解人工智能
本系列共 42 篇,分为八大模块:
- 📖 模块一【AI 基础概念】(3 篇):AI/ML/DL 关系、学习方式、深度之谜
- 🧠 模块二【神经网络入门】(4 篇):神经元、权重、激活函数、MLP
- 🏗️ 模块三【深度学习核心】(6 篇):损失函数、梯度下降、反向传播、过拟合、Batch/Epoch/LR
- 🎯 模块四【注意力机制】(5 篇):从 Attention 到 Transformer
- 🔬 模块五【NCT 与 CATS-NET 案例】(8 篇):真实架构演进全记录
- 🔄 模块六【CATS-NCT诞生记】(6 篇):概念抽象、原型学习与架构演进
- ⚙️ 模块七【参数调优实战】(6 篇):学习率、正则化、超参数搜索
- 🚀 模块八【综合应用展望】(4 篇):未来趋势与职业规划
本文是模块六第 3 篇,带你深入理解原型库的设计与工作机制。👨💻 作者简介:NeuroConscious Research Team,一群热爱 AI 科普的研究者,专注于神经科学启发的 AI架构设计与可解释性研究。理念:“再复杂的概念,也能用大白话讲清楚”。
💻 项目地址:https://github.com/wyg5208/nct.git
🌐 官网地址:https://neuroconscious.link
📝 作者 CSDN:https://blog.csdn.net/yweng18
📦 NCT PyPI:https://pypi.org/project/neuroconscious-transformer/
⭐ 欢迎 Star⭐、Fork🍴、贡献代码🤝
📌 本文核心比喻:字典/概念卡片
⏱️ 阅读时间:约 25 分钟
🎯 学习目标:理解原型学习、原型匹配机制、原型更新过程
📝 文章摘要

本文介绍 CATS-NCT 的"概念词典"——原型库。想象一本字典:每个词条对应一个概念,你查一个字就能找到它的解释。CATS-NCT 的原型库也是类似的结构:100 个可学习的原型向量,每个代表一个基础概念。当 AI 遇到新事物时,它会"查词典",找出最匹配的原型,从而理解这个概念。这是实现概念学习和知识迁移的关键机制。
🎯 你需要先了解
阅读本文前,建议你:
- ✅ 了解概念抽象模块(参考第 27 篇)
- ✅ 知道什么是向量相似度(余弦相似度)
- ✅ 了解 Softmax 函数
如果还没读前文,点这里返回
📖 正文
一、原型库是什么?
1.1 核心概念
原型库 = 一组可学习的向量,每个向量代表一个基础概念
在 CATS-NCT 中:
- 原型数量:100 个
- 每个原型维度:64 维(与概念向量相同)
- 初始化:随机向量(Xavier 初始化)
- 学习:通过训练自动调整
类比:字典的词条
- 原型 = 字典中的词条(如"猫"、“狗”、“红色”)
- 原型向量 = 词条的解释内容
- 原型库 = 整本字典
1.2 生物启发:语义细胞
人脑中有专门的"概念细胞"(Concept Cells):
Jennifer Aniston 神经元
- 2005 年,科学家 Quiroga 等人发现
- 某些神经元只对特定概念响应
- 看到 Jennifer Aniston 的照片、名字、甚至想到她时
- 同一个神经元都会强烈激活
Halle Berry 神经元
- 另一个著名的概念细胞
- 对她的照片、名字、甚至扮相都有响应
启示
- 大脑用专门的神经元编码抽象概念
- 这些概念是稀疏的(只有少数神经元参与)
- 这些概念是鲁棒的(不同形式都能触发)
1.3 原型 vs 聚类中心
| 特性 | 传统聚类中心 | CATS-NCT 原型 |
|---|---|---|
| 来源 | 数据统计 | 端到端学习 |
| 更新方式 | K-Means 迭代 | 梯度下降 |
| 与任务关系 | 无关 | 与下游任务联合优化 |
| 可解释性 | 较低 | 较高(稀疏激活) |
| 灵活性 | 固定 | 可微分、可训练 |
原型不是简单的聚类中心,而是与任务联合优化的可学习参数。
聚类中心:
- 只看数据分布
- 可能聚出一些对任务无用的类别
原型:
- 考虑下游任务
- 学习对分类/预测有用的概念
- 通过梯度下降自动调整
二、原型匹配机制
2.1 匹配流程

匹配过程:
原型匹配流程
输入: 概念向量 [64D]
步骤 1:计算相似度
| 原型 | 相似度 |
|---|---|
| 原型 1 | 0.85 |
| 原型 2 | 0.12 |
| 原型 3 | 0.67 |
| … | … |
| 原型 100 | 0.05 |
步骤 2:Softmax 归一化(带温度参数)
| 原型 | 权重 | 说明 |
|---|---|---|
| 原型 1 | 0.52 | ← 最匹配 |
| 原型 2 | 0.08 | |
| 原型 3 | 0.31 | |
| … | … | |
| 原型 100 | 0.01 |
输出: 原型权重分布 [100D](稀疏、可解释)
2.2 余弦相似度
公式:
cosine_similarity(A, B) = (A · B) / (||A|| × ||B||)
含义:
- 计算两个向量夹角的余弦值
- 值域:[-1, 1]
- 1:方向完全相同
- 0:正交(无关)
- -1:方向相反
为什么用余弦相似度?
- 忽略大小:只关心方向,不关心长度
- 有界:结果在 [-1, 1] 之间,好解释
- 高效:只需点积和归一化
代码实现:
import torch
import torch.nn.functional as F
# 归一化原型和概念向量
prototypes_norm = F.normalize(prototypes, p=2, dim=1) # [100, 64]
concept_norm = F.normalize(concept_vector, p=2, dim=1) # [B, 64]
# 计算余弦相似度
cosine_sim = concept_norm @ prototypes_norm.t() # [B, 100]
2.3 软分配与温度参数
软分配公式:
weights = softmax(cosine_similarity / τ)
其中 τ(tau)是温度参数:
τ 很小(如 0.05):
- 分布很"尖锐"
- 接近 one-hot(只有一个原型激活)
- 类似"硬分配"
τ 很大(如 1.0):
- 分布很"平滑"
- 多个原型同时激活
- 更"软"的分配
CATS-NCT 选择 τ = 0.1:
- 平衡尖锐性和平滑性
- 既保持可解释性,又允许一定模糊性
温度参数效果对比:
| 温度 τ | 权重分布 | 特点 |
|---|---|---|
| 0.05 | [0.95, 0.02, 0.02, …] | 很尖锐,接近硬分配 |
| 0.1 | [0.70, 0.20, 0.08, …] | 较尖锐,主要一个原型 ✅ |
| 0.5 | [0.40, 0.30, 0.20, …] | 较平滑,多个原型 |
| 1.0 | [0.15, 0.12, 0.11, …] | 很平滑,接近均匀 |
代码实现:
# 软分配(带温度)
temperature = 0.1
prototype_weights = F.softmax(cosine_sim / temperature, dim=-1)
三、原型的学习过程
3.1 初始化:K-Means
随机初始化(Xavier):
- 从均匀分布随机采样
- 通过 1/sqrt(dim) 缩放
- 保证初始梯度稳定
K-Means 初始化(可选):
- 在一些数据上跑 K-Means
- 用聚类中心作为初始原型
- 加速收敛,但可能陷入局部最优
CATS-NCT 的选择:
- 默认:Xavier 随机初始化
- 理由:简单、通用、不依赖预训练数据
Xavier 初始化代码:
import torch.nn as nn
# 原型参数
self.prototypes = nn.Parameter(torch.randn(n_prototypes, concept_dim))
# Xavier 初始化
nn.init.xavier_uniform_(self.prototypes)
3.2 训练中的更新

学习机制:
训练迭代:
Epoch 1:
输入:猫的图片
概念向量:[0.3, -0.5, 0.8, ...] (64D)
匹配:原型 #7 最相似
更新:原型 #7 向"猫概念"方向移动
Epoch 10:
输入:另一只猫
概念向量:[0.4, -0.4, 0.7, ...]
匹配:还是原型 #7
更新:原型 #7 更精确地代表"猫"
Epoch 100:
原型 #7 = "猫"概念
原型 #23 = "狗"概念
原型 #45 = "红色"概念
...
3.3 指数移动平均(EMA)更新
问题:直接梯度更新可能导致原型震荡
解决方案:使用指数移动平均
prototype_new = α × prototype_old + (1-α) × prototype_update
其中 α = 0.99(动量系数)
好处:
- 稳定:原型不会剧烈变化
- 平滑:整合历史信息
- 鲁棒:对噪声更容忍
代码实现:
# 简化版 EMA 更新(实际在优化器中实现)
def ema_update(prototype, update, momentum=0.99):
return momentum * prototype + (1 - momentum) * update
3.4 多样性约束
问题:如果不加约束,所有原型可能变得相似
- 原型 1 ≈ 原型 2 ≈ 原型 3
- 失去区分不同概念的能力
解决方案:多样性损失
- 鼓励原型彼此正交
- 原型 A · 原型 B ≈ 0
效果:
- 每个原型代表不同的概念
- 原型空间覆盖更均匀
- 提高表征能力
四、原型库的应用
4.1 概念重构
# 通过原型权重重构概念向量
reconstructed = prototype_weights @ prototypes
# 维度变化:
# prototype_weights: [B, 100]
# prototypes: [100, 64]
# reconstructed: [B, 64]
重构的意义:
- 验证原型是否保留了足够信息
- 计算重构损失指导训练
- 可以"生成"概念(类似字典查询)
4.2 可解释性分析
我们可以知道:
-
哪些原型被激活?
- 输入猫的图片 → 原型 #7、#12 激活
- 输入狗的图片 → 原型 #23、#31 激活
- 输入猫的图片 → 原型 #7、#12 激活
-
激活强度如何?
- 原型 #7: 0.70(强激活)
- 原型 #12: 0.25(弱激活)
- 原型 #7: 0.70(强激活)
-
原型代表什么?
- 通过分析激活该原型的输入
- 推断原型代表的语义
- 通过分析激活该原型的输入
优势:
- 比黑盒神经网络更可解释
- 可以"调试"概念学习
- 便于知识编辑和迁移
4.3 知识迁移
原型库使得知识迁移变得简单:
教师网络 学生网络
| |
├── 原型库(已训练好) ─────→ ├── 复制原型库
| |
└── 概念空间对齐 ───────────→ └── 快速适应
迁移方式:
- 直接复制:复制教师的原型库
- 对齐映射:学习教师到学生的映射
- 联合训练:师生共享原型空间
五、可视化原型
5.1 t-SNE 可视化

可视化步骤:
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
# 获取原型向量
prototypes = ca_module.prototypes.detach().numpy() # [100, 64]
# t-SNE 降维到 2D
tsne = TSNE(n_components=2, random_state=42)
prototypes_2d = tsne.fit_transform(prototypes)
# 绘制
plt.figure(figsize=(10, 8))
plt.scatter(prototypes_2d[:, 0], prototypes_2d[:, 1],
c=range(100), cmap='tab20', s=100)
plt.colorbar(label='Prototype ID')
plt.title('Prototype Distribution (t-SNE)')
plt.xlabel('Dimension 1')
plt.ylabel('Dimension 2')
plt.savefig('images/img_28_prototype_tsne.png', dpi=150)
plt.show()
观察结果:
- 相似的原型聚集在一起
- 形成有意义的簇(如"动物"、“颜色”、“形状”)
- 原型空间结构清晰
5.2 原型激活热图
# 可视化多个样本的原型激活
import numpy as np
# 获取 10 个样本的激活
sample_weights = prototype_weights[:10].numpy()
plt.figure(figsize=(12, 6))
plt.imshow(sample_weights, aspect='auto', cmap='YlOrRd')
plt.colorbar(label='Activation Weight')
plt.xlabel('Prototype ID')
plt.ylabel('Sample ID')
plt.title('Prototype Activation Heatmap')
plt.savefig('images/img_28_prototype_heatmap.png', dpi=150)
plt.show()
5.3 原型使用频率统计
# 统计每个原型的使用频率
usage_frequency = prototype_weights.mean(dim=0) # [100]
# 找出最活跃的原型
top_k = 10
top_prototypes = torch.topk(usage_frequency, k=top_k)
print(f"Top {top_k} 最活跃原型:")
for i, (idx, freq) in enumerate(zip(top_prototypes.indices, top_prototypes.values)):
print(f" {i+1}. 原型 #{idx.item()}: {freq.item():.4f}")
六、实战:探索原型库
6.1 完整演示代码
import torch
import torch.nn.functional as F
from cats_nct.core import ConceptAbstractionModule
print("="*60)
print("原型库探索演示")
print("="*60)
# 创建概念抽象模块
ca = ConceptAbstractionModule(
d_model=768,
concept_dim=64,
n_prototypes=100,
temperature=0.1,
)
# 生成模拟数据(假设来自全局工作空间)
torch.manual_seed(42)
batch_size = 5
representations = torch.randn(batch_size, 768)
# 前向传播
output = ca(representations)
concept_vector = output['concept_vector']
prototype_weights = output['prototype_weights']
print(f"\n输入表征: {representations.shape}")
print(f"概念向量: {concept_vector.shape}")
print(f"原型权重: {prototype_weights.shape}")
6.2 分析原型激活
# 分析每个样本的 Top-3 原型
print("\n" + "="*60)
print("各样本的 Top-3 激活原型")
print("="*60)
for i in range(batch_size):
top3 = torch.topk(prototype_weights[i], k=3)
print(f"\n样本 {i}:")
for j, (idx, weight) in enumerate(zip(top3.indices, top3.values)):
print(f" #{j+1}: 原型 {idx.item():2d} (权重: {weight.item():.3f})")
6.3 观察稀疏性
# 统计活跃原型数(权重 > 0.01)
active_counts = (prototype_weights > 0.01).sum(dim=1)
print("\n" + "="*60)
print("稀疏性统计")
print("="*60)
print(f"平均活跃原型数: {active_counts.float().mean():.1f} / 100")
print(f"稀疏度: {1 - active_counts.float().mean() / 100:.1%}")
6.4 原型相似度矩阵
import matplotlib.pyplot as plt
# 计算原型间余弦相似度
prototypes = ca.prototypes.detach()
prototypes_norm = F.normalize(prototypes, p=2, dim=1)
similarity_matrix = prototypes_norm @ prototypes_norm.t()
# 可视化前 20 个原型的相似度
plt.figure(figsize=(10, 8))
plt.imshow(similarity_matrix[:20, :20].numpy(), cmap='coolwarm', vmin=-1, vmax=1)
plt.colorbar(label='Cosine Similarity')
plt.xlabel('Prototype ID')
plt.ylabel('Prototype ID')
plt.title('Prototype Similarity Matrix (Top 20)')
plt.savefig('images/img_28_prototype_similarity.png', dpi=150)
plt.show()
⚠️ 常见误区
❌ 误区 1:“原型就是聚类中心”
真相:
原型和聚类中心有本质区别。聚类中心是数据统计的结果,原型是与任务联合优化的可学习参数。原型会随训练不断调整,以更好地服务下游任务。
对比:
| 特性 | K-Means 聚类中心 | CATS-NCT 原型 |
|---|---|---|
| 优化目标 | 最小化类内距离 | 最小化任务损失 |
| 更新方式 | 迭代算法 | 梯度下降 |
| 与任务关系 | 无关 | 紧密相关 |
| 可微分 | 否 | 是 |
❌ 误区 2:“每个原型对应一个词”
真相:
原型是隐式的,不一定对应人类语言的某个词。一个原型可能对应多个相关概念(如"猫科动物"),也可能只对应概念的某个方面(如"毛茸茸")。需要通过分析激活该原型的输入来理解其语义。
❌ 误区 3:“原型数量越多越好”
真相:
原型数量需要权衡。太多会导致:
- 计算成本增加
- 稀疏性降低(每个原型激活少)
- 过拟合风险
CATS-NCT 选择 100 个原型是经过实验验证的,对于一般任务足够。
❌ 误区 4:“原型一旦训练好就不能变”
真相:
原型是可学习的参数,在持续学习中可以不断更新。遇到新类别的数据时,原型库可以自适应调整,甚至添加新的原型。
💡 一句话总结
原型库 = AI 的概念词典
通过 100 个可学习原型实现概念表示,用余弦相似度进行软匹配,用稀疏性和多样性约束保证概念质量,让 AI 拥有可解释的概念思维能力。
记忆口诀:
原型库,概念典,
一百向量六四维。
余弦相似来匹配,
软分配,温度调。
稀疏多样双约束,
概念学习真精妙!
📚 延伸阅读
-
原型学习理论
- Prototypical Networks for Few-shot Learning
- 核心思想:用原型表示类别
-
向量量化(VQ-VAE)
- Neural Discrete Representation Learning
- 离散化表征学习
-
概念细胞研究
- Quiroga et al., “Invariant visual representation by single neurons”
- 人脑概念编码的神经科学基础
-
可解释性 AI
- Concept Activation Vectors (CAV)
- 用概念解释神经网络决策
✍️ 课后作业
选择题(每题 10 分)
1. CATS-NCT 的原型库有多少个原型?
A. 50
B. 64
C. 100 ✅
D. 768
2. 原型匹配的相似度计算使用什么方法?
A. 欧氏距离
B. 曼哈顿距离
C. 余弦相似度 ✅
D. 汉明距离
3. 温度参数 τ 越小,权重分布越?
A. 平滑
B. 尖锐 ✅
C. 均匀
D. 随机
4. 原型和聚类中心的主要区别是?
A. 维度不同
B. 原型是可学习的,与任务联合优化 ✅
C. 数量不同
D. 初始化方式不同
思考题(20 分)
讨论:原型库如何让 AI 拥有"可解释性"?对比传统神经网络的黑盒特性,原型库的优势在哪里?
提示:
- 可以知道哪些概念被激活
- 可以分析原型代表的语义
- 可以编辑和迁移知识
代码题(20 分)
任务:实现一个简单的原型网络,观察原型学习过程。
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimplePrototypeLayer(nn.Module):
"""简单原型层"""
def __init__(self, input_dim=64, n_prototypes=10):
super().__init__()
self.n_prototypes = n_prototypes
# TODO: 初始化原型参数
self.prototypes = nn.Parameter(
# 你的代码:随机初始化 n_prototypes 个 input_dim 维向量
)
# Xavier 初始化
nn.init.xavier_uniform_(self.prototypes)
self.temperature = 0.1
def forward(self, x):
"""
Args:
x: [B, input_dim] 输入向量
Returns:
weights: [B, n_prototypes] 原型权重
"""
# TODO: 1. 归一化原型和输入
# TODO: 2. 计算余弦相似度
# TODO: 3. 软分配(带温度)
return weights
# 测试
layer = SimplePrototypeLayer(input_dim=64, n_prototypes=10)
x = torch.randn(5, 64)
weights = layer(x)
print(f"输入: {x.shape}")
print(f"原型: {layer.prototypes.shape}")
print(f"权重: {weights.shape}")
print(f"权重和: {weights.sum(dim=1)}") # 应该接近 1
📝 下一篇预告
题目:分层门控:概念如何控制行为
我们会学到:
- 为什么需要门控机制
- 三级门控的设计(全局→模块→调制)
- 门控与概念的交互
- 不同概念触发的门控模式
作者:NeuroConscious Research Team
更新时间:2026 年 4 月
版本号:V1.0(图文并茂版)
更多推荐

所有评论(0)