教程 1:构建和使用 CANN 模型¶
Note
阅读时间: 25-30 分钟
难度: 初级
前提条件: Python 基础、NumPy/JAX 数组操作
本教程将帮助您理解 CANNs 库中模型的构建方式,以及如何使用内置的 Wu-Amari-Wong (WAW) 连续吸引子神经网络(CANNs) [5, 6, 7, 8] 模型。
1. BrainPy 框架介绍¶
CANNs 库中的所有模型均基于 BrainPy 框架 [18] 构建。BrainPy 是脑模拟生态系统中用于动力系统的核心框架,基于 JAX 构建,支持 JIT 编译与自动微分。
1.1 核心概念¶
在开始之前,您需要理解以下关键概念:
动力学抽象¶
所有 CANN 模型均继承自 bp.DynamicalSystem——这是用于定义动力系统的基类。它提供:
状态管理机制
时间步管理
JIT 编译支持
[1]:
import brainpy as bp
import brainpy.math as bm
class MyModel(bp.DynamicalSystem):
def update(self, inp):
# Define single-step dynamics update
pass
状态容器¶
BrainPy 提供状态容器以管理不同类型变量:
[2]:
def __init__(self):
super().__init__()
# State variable: neuron membrane potential
self.u = bm.Variable(bm.zeros(self.num))
# State variable: neuron firing rate
self.r = bm.Variable(bm.zeros(self.num))
# External input state
self.inp = bm.Variable(bm.zeros(self.num))
时间步管理¶
BrainPy 通过 bm.set_dt() 管理模拟时间步:
[3]:
import brainpy.math as bm # :cite:p:`wang2023brainpy`
# Set simulation time step (unit: milliseconds)
bm.set_dt(0.1)
# Get current time step in the model
dt = bm.get_dt()
重要: 在运行任何模拟之前,必须设置时间步 dt——否则模型将抛出错误。
进一步学习¶
如需深入了解 BrainPy 框架 [18],请参阅:
2. CANN1D 实现分析¶
我们以 CANN1D 为例,了解完整 CANN 模型的实现方式。
2.1 模型继承结构¶
bp.DynamicalSystem
└── BasicModel
└── BaseCANN
└── BaseCANN1D
└── CANN1D
2.2 初始化方法 __init__¶
CANN1D 的初始化方法定义了所有模型参数:
[ ]:
class CANN1D(BaseCANN1D):
def __init__(
self,
num: int, # Number of neurons
tau: float = 1.0, # Time constant
k: float = 8.1, # Global inhibition strength
a: float = 0.5, # Connection width
A: float = 10, # External input amplitude
J0: float = 4.0, # Synaptic connection strength
z_min: float = -π, # Feature space minimum
z_max: float = π, # Feature space maximum
**kwargs,
):
...
这些参数控制网络的动力学行为。我们将在 教程 4 中详细探讨每个参数的作用。
2.3 连接矩阵生成 make_conn¶
make_conn 方法生成神经元之间的连接矩阵。CANN 使用高斯连接核——具有相似特征偏好的神经元之间具有更强的兴奋性连接:
[ ]:
def make_conn(self):
# Calculate distances between all neuron pairs
x_left = bm.reshape(self.x, (-1, 1))
x_right = bm.repeat(self.x.reshape((1, -1)), len(self.x), axis=0)
d = self.dist(x_left - x_right)
# Compute connection strength using Gaussian function
return (
self.J0
* bm.exp(-0.5 * bm.square(d / self.a))
/ (bm.sqrt(2 * bm.pi) * self.a)
)
2.4 刺激生成 get_stimulus_by_pos¶
get_stimulus_by_pos 根据特征空间中的指定位置生成外部刺激(高斯形波包):
[ ]:
def get_stimulus_by_pos(self, pos):
return self.A * bm.exp(
-0.25 * bm.square(self.dist(self.x - pos) / self.a)
)
该方法由任务模块调用,用于生成输入数据。
2.5 动力学更新 update¶
update 方法定义了网络的单步动力学更新:
[ ]:
def update(self, inp):
self.inp.value = inp
# Compute firing rate (divisive normalization)
r1 = bm.square(self.u.value)
r2 = 1.0 + self.k * bm.sum(r1)
self.r.value = r1 / r2
# Compute recurrent input
Irec = bm.dot(self.conn_mat, self.r.value)
# Update membrane potential using Euler method
self.u.value += (
(-self.u.value + Irec + self.inp.value)
/ self.tau * bm.get_dt()
)
3. 如何使用内置 CANN 模型¶
现在我们学习如何实际使用内置的 CANN 模型。
3.1 基本使用流程¶
[4]:
import brainpy.math as bm
from canns.models.basic import CANN1D
# Step 1: Set time step
bm.set_dt(0.1)
# Step 2: Create model instance
model = CANN1D(
num=256, # 256 neurons
tau=1.0, # Time constant
k=8.1, # Global inhibition
a=0.5, # Connection width
A=10, # Input amplitude
J0=4.0, # Connection strength
)
# Step 3: View model information
print(f"Number of neurons: {model.shape}")
print(f"Feature space range: [{model.z_min}, {model.z_max}]")
print(f"Connection matrix shape: {model.conn_mat.shape}")
Number of neurons: (256,)
Feature space range: [-3.141592653589793, 3.141592653589793]
Connection matrix shape: (256, 256)
3.2 运行单步更新¶
[5]:
# Generate external stimulus at pos=0
pos = 0.0
stimulus = model.get_stimulus_by_pos(pos)
# Run two step update
model(stimulus) # or you can explicitly call model.update(stimulus)
model(stimulus)
# View current state
print(f"Firing rate shape: {model.r.value.shape}")
print(f"Max firing rate: {bm.max(model.r.value):.4f}")
print(f"Max membrane potential: {bm.max(model.u.value):.4f}")
Firing rate shape: (256,)
Max firing rate: 0.0024
Max membrane potential: 1.9275
3.3 完整示例¶
以下是创建并测试 CANN1D 模型的完整示例:
[6]:
import brainpy.math as bm # :cite:p:`wang2023brainpy`
from canns.models.basic import CANN1D
# Setup environment
bm.set_dt(0.1)
# Create model (auto-initializes)
model = CANN1D(num=256, tau=1.0, k=8.1, a=0.5, A=10, J0=4.0)
# Print basic model information
print("=" * 50)
print("CANN1D Model Information")
print("=" * 50)
print(f"Number of neurons: {model.shape}")
print(f"Time constant tau: {model.tau}")
print(f"Global inhibition k: {model.k}")
print(f"Connection width a: {model.a}")
print(f"Input amplitude A: {model.A}")
print(f"Connection strength J0: {model.J0}")
print(f"Feature space: [{model.z_min:.2f}, {model.z_max:.2f}]")
print(f"Neural density rho: {model.rho:.2f}")
# Test stimulus generation
pos = 0.5
stimulus = model.get_stimulus_by_pos(pos)
print(f"\nStimulus position: {pos}")
print(f"Stimulus shape: {stimulus.shape}")
print(f"Max stimulus value: {bm.max(stimulus):.4f}")
# Run several update steps
print("\nRunning 100 update steps...")
for _ in range(100):
model(stimulus)
print(f"Max firing rate: {bm.max(model.r.value):.6f}")
print(f"Max membrane potential: {bm.max(model.u.value):.6f}")
==================================================
CANN1D Model Information
==================================================
Number of neurons: (256,)
Time constant tau: 1.0
Global inhibition k: 8.1
Connection width a: 0.5
Input amplitude A: 10
Connection strength J0: 4.0
Feature space: [-3.14, 3.14]
Neural density rho: 40.74
Stimulus position: 0.5
Stimulus shape: (256,)
Max stimulus value: 9.9997
Running 100 update steps...
Max firing rate: 0.002427
Max membrane potential: 10.278063
4. 内置模型概览¶
CANNs 库提供三类内置模型:
基础模型¶
标准 CANN 实现及其变体:
CANN1D——一维连续吸引子神经网络CANN1D_SFA——带有尖峰频率适应的 CANN1DCANN2D——二维连续吸引子神经网络CANN2D_SFA——带有 SFA 的 CANN2D分层路径积分网络(网格细胞、位置细胞、带状细胞等)
Theta 扫描模型
脑启发模型¶
基于神经科学原理的学习模型:
Hopfield 网络
…
混合模型¶
CANN 与人工神经网络的组合(开发中)。
详细信息: 请参阅核心概念文档,获取完整模型列表与使用案例。
恭喜您完成第一个 CANN 建模教程!您现在已理解:
CANN 的基本架构及其神经动力学
如何创建 CANN1D 和 CANN2D 模型
关键参数(
num,k,tau,a,A,J0)的作用如何运行模拟并观察网络状态
您已掌握的内容¶
- 模型创建
您能够使用自定义参数实例化 CANN 模型,并理解每个参数的控制作用。
- 网络动力学
您理解了连续吸引子动力学——局部兴奋与全局抑制如何形成稳定的活动波包。
- 状态变量
您知道如何访问内部状态(
u表示突触输入,r表示放电率)。
继续学习¶
现在,您可以进入下一个教程:
教程 2:任务生成与模拟——学习如何生成导航任务并运行带外部输入的完整模拟
随后继续学习:
教程 3:分析与可视化——学习 CANN 动力学的可视化工具
教程 4:参数效应——系统性探索参数对动力学的影响
关键要点¶
CANN 是动力系统——它们根据微分方程随时间演化
波包是吸引子——局部活动模式是动力学的稳定不动点
参数至关重要——不同参数组合会产生不同的动力学行为
BrainPy 处理复杂性——框架自动管理状态变量与时间步进
下一步:教程 2:任务生成与模拟