如何利用Bindsnet-Python模拟脉冲神经网络(SNN)?Part III. 运行仿真程序(Running Simulations)
作者:互联网
系列文章目录
微信搜索:脑机接口研习社
关注我们,了解脑机接口最新进展
文章目录
一、运行仿真程序(Running Simulations)
建立Network对象后,下一步是运行仿真程序。
使用代码Network.run运行此功能。
Network.run接收的参数包括:
inputs——将子类AbstractAbstract的层的名称映射成字典,并以[time,batch_size,* input_shape]的形式输入数据,其中input_shape是数据要传递到的神经元群体的形状。
time——时间步长的模拟次数,通常被认为是毫秒。
clamp和unclamp——用于强迫神经元在任何给定的时间步长达到峰值、进行脉冲(或不进行脉冲)。
reward——提供奖励调制的学习规则。
masks——是字典映射到布尔张量的连接,该布尔张量指定将哪个突触权重钳位为零。
基于前面的教程,我们在此提供一个简单的端到端(end-to-end)的示例,用于模拟两层、输入-输出的脉冲神经网络。
前面的教程戳下面的链接:
Part II. Adding Network Components
代码示例:
import torch
import matplotlib.pyplot as plt
from bindsnet.network import Network
from bindsnet.network.nodes import Input, LIFNodes
from bindsnet.network.topology import Connection
from bindsnet.network.monitors import Monitor
from bindsnet.analysis.plotting import plot_spikes, plot_voltages
# Simulation time.
time = 500
# Create the network.
network = Network()
# Create and add input, output layers.
source_layer = Input(n=100)
target_layer = LIFNodes(n=1000) #node=neural
network.add_layer(
layer=source_layer, name="A"
)
network.add_layer(
layer=target_layer, name="B"
)
# Create connection between input and output layers.
forward_connection = Connection( #模拟神经元不断向前的连接
source=source_layer,
target=target_layer,
w=0.05 + 0.1 * torch.randn(source_layer.n, target_layer.n), # Normal(0.05, 0.01) weights.
)
#torch.randn是生成一个随机矩阵,有source_layer.n行、target_layer.n列
network.add_connection(
connection=forward_connection, source="A", target="B"
)
# Create recurrent connection in output layer.
recurrent_connection = Connection(
source=target_layer,
target=target_layer,
w=0.025 * (torch.eye(target_layer.n) - 1), # Small, inhibitory "competitive" weights.
)
network.add_connection(
connection=recurrent_connection, source="B", target="B"
)
# Create and add input and output layer monitors.
source_monitor = Monitor(
obj=source_layer,
state_vars=("s",), # Record spikes and voltages.
time=time, # Length of simulation (if known ahead of time).
)
target_monitor = Monitor(
obj=target_layer,
state_vars=("s", "v"), # Record spikes and voltages.
time=time, # Length of simulation (if known ahead of time).
)
network.add_monitor(monitor=source_monitor, name="A")
network.add_monitor(monitor=target_monitor, name="B")
# Create input spike data, where each spike is distributed according to Bernoulli(0.1).
input_data = torch.bernoulli(0.1 * torch.ones(time, source_layer.n)).byte()
inputs = {"A": input_data}
# Simulate network on input data.
network.run(inputs=inputs, time=time)
# Retrieve and plot simulation spike, voltage data from monitors.
spikes = {
"A": source_monitor.get("s"), "B": target_monitor.get("s")
}
voltages = {"B": target_monitor.get("v")}
plt.ioff()
plot_spikes(spikes)
plot_voltages(voltages, plot_type="line")
plt.show()
输出结果:
在上面的电压图中可以看到,LIFNodes对象的默认阈值设置下,没有电压高于-52mV。达到这一高位电压后,神经元的电压将重置为-64mV。
二、仿真笔记(Simulation Notes)
所有网络组件的仿真都是同步的、或者说是“时钟驱动的”(synchronous or clock-driven。也就是说,所有元件都会在每个时间步(time step)进行更新。
其他框架使用事件驱动(event-driven)的仿真,其中脉冲(spike)可以在任意时间处发生,而不是只在dt的倍数处发生。
由于易于实现且出于计算效率的考虑,我们选择了时钟驱动的仿真。
在“模拟”(simulation)这一步骤中,每个层的输入(inputs)将计算为所有与它连接的前一个模拟时间步的所有输出(outputs)的总和,由突触权重进行加权,由bindsnet.network.Network类的_get_inputs方法实现。
该模型使我们能够解耦网络元件,并在所选dt的时间粒度上分别执行其仿真,仅在仿真步骤之间进行交互。
这与深度神经网络(DNN)的计算完全不同。
DNN是假定了层的排序,并且是在单个时间步中从最浅层到最深层按顺序计算了层的激活。除了循环层(recurrent layers)例外,循环层的计算仍然按照时间排序。
三、内容总结
下节将介绍建立和添加学习规则(Creating and Adding learning rules)。
未完待续……
参考链接:
https://bindsnet-docs.readthedocs.io/guide/guide_part_i.html#adding-network-components
图源/谷歌图片
标签:layer,network,Python,time,monitor,source,Running,target,Bindsnet 来源: https://blog.csdn.net/weixin_44099023/article/details/115324171