(三)一个前馈脉冲神经网络


  1. 了解如何简化LIF神经元,使其适合深度学习

  2. 实现前馈脉冲神经网络(SNN)

$ pip install snntorch
# imports
import snntorch as snn
from snntorch import spikeplot as splt
from snntorch import spikegen

import torch
import torch.nn as nn
import matplotlib.pyplot as plt

1. 简化的LIF神经元模型

1.1 衰减率

在这里插入图片描述

1.2 加权输入电流

在这里插入图片描述
在未来的模拟中, W和β 的效应是分开的。 W是一个独立于 β更新的可学习参数。

1.3 脉冲发射和重置

在这里插入图片描述
如果触发了脉冲,膜电位应该被重置。 通过减法重置机制可以这样建模:
在这里插入图片描述
由于 W 是一个可学习参数,而 Uthr通常只是设为 1(尽管也可以调整),这样就只剩下衰减率 β作为需要指定的唯一超参数。

1.4 代码

用 Python 实现这个神经元的代码如下所示:

def leaky_integrate_and_fire(mem, x, w, beta, threshold=1):
  spk = (mem > threshold) # 如果膜电位超过阈值,spk=1,否则为0
  mem = beta * mem + w*x - spk*threshold
  return spk, mem

在这里插入图片描述

# 设置神经元参数
delta_t = torch.tensor(1e-3)
tau = torch.tensor(5e-3)
beta = torch.exp(-delta_t/tau)

衰减率是: 0.819

运行一个快速模拟,以检查神经元对阶跃电压输入的响应是否正确:

num_steps = 200

# initialize inputs/outputs + small step current input
x = torch.cat((torch.zeros(10), torch.ones(190)*0.5), 0)#输入
mem = torch.zeros(1)#膜电位
spk_out = torch.zeros(1)#输出
mem_rec = []
spk_rec = []

# neuron parameters
w = 0.4
beta = 0.819

# neuron simulation
for step in range(num_steps):
  spk, mem = leaky_integrate_and_fire(mem, x[step], w=w, beta=beta)
  mem_rec.append(mem)
  spk_rec.append(spk)

# convert lists to tensors
mem_rec = torch.stack(mem_rec)
spk_rec = torch.stack(spk_rec)

plot_cur_mem_spk(x*w, mem_rec, spk_rec, thr_line=1,ylim_max1=0.5,
                 title="LIF Neuron Model With Weighted Step Voltage")

在这里插入图片描述

2.在SNNTORCH中的LEAKY神经元模型

我们可以通过实例化 snn.Leaky 来实现相同的功能,在这方面和我们在上一个教程中使用的 snn.Lapicque 类似,但参数更少:

lif1 = snn.Leaky(beta=0.8)

现在神经元模型存储在lif1中。使用这个神经元:
输入
cur_in:W*X[t]的每个元素依次作为输入传递
mem:之前步骤的膜电位,U[t-1],也可作为输入传递
输出
spk_out:输出脉冲St
mem:当前步骤膜电位U[t]

# 小幅度电流输入
w=0.21
cur_in = torch.cat((torch.zeros(10), torch.ones(190)*w), 0)
mem = torch.zeros(1)
spk = torch.zeros(1)
mem_rec = []
spk_rec = []

# 神经元模拟
for step in range(num_steps):
  spk, mem = lif1(cur_in[step], mem)
  mem_rec.append(mem)
  spk_rec.append(spk)

# 将列表转换为张量
mem_rec = torch.stack(mem_rec)
spk_rec = torch.stack(spk_rec)

plot_cur_mem_spk(cur_in, mem_rec, spk_rec, thr_line=1, ylim_max1=0.5,
                 title="snn.Leaky 神经元模型")

在这里插入图片描述

3. 一个前馈脉冲神经网络

到目前为止,我们只考虑了单个神经元对输入刺激的响应。snnTorch将其扩展为深度神经网络变得简单。在本节中,我们将创建一个3层全连接神经网络,维度为784-1000-10。 与迄今为止的模拟相比,每个神经元现在将整合更多的输入脉冲。
在这里插入图片描述
PyTorch用于形成神经元之间的连接,snnTorch用于创建神经元。首先,初始化所有层。

# 层参数
num_inputs = 784
num_hidden = 1000
num_outputs = 10
beta = 0.99

# 初始化层
fc1 = nn.Linear(num_inputs, num_hidden)
lif1 = snn.Leaky(beta=beta)
fc2 = nn.Linear(num_hidden, num_outputs)
lif2 = snn.Leaky(beta=beta)

接下来,初始化每个脉冲神经元的隐藏变量和输出。随着网络规模的增加,这变得更加繁琐,可以使用静态方法 init_leaky() 来处理这个问题。 snnTorch中的所有神经元都有自己的初始化方法,遵循相同的语法,例如 init_lapicque()。隐藏状态的形状会在第一次前向传递期间根据输入数据的维度自动初始化。

# 初始化隐藏状态
mem1 = lif1.init_leaky()
mem2 = lif2.init_leaky()

# 记录输出
mem2_rec = []
spk1_rec = []
spk2_rec = []

创建一个输入脉冲列以传递给网络。需要模拟784个输入神经元的200个时间步骤,即原始输入的维度为 200x784。 然而,神经网络通常以小批量方式处理数据。snnTorch使用时间优先的维度:
[时间x批次大小x特征维度]
因此,将输入沿着 dim=1 进行“unsqueeze”以指示“一个批次”的数据。这个输入张量的维度必须是 200 x 1 x784:

spk_in = spikegen.rate_conv(torch.rand((200, 784))).unsqueeze(1)

PyTorch将神经元连接在一起,而snnTorch将结果加载到脉冲神经元模型中。
顺序说明:
从 spk_in 的第 i 输入到第 j 神经元的权重由 nn.Linear 中初始化的参数加权: Xi*Wij

这生成了方程输入电流项的输入,贡献给脉冲神经元的 U[t+1]

如果U[t+1]>Uthr ,则从该神经元触发一个脉冲

这个脉冲由第二层权重加权,然后对所有输入、权重和神经元重复上述过程。

如果没有脉冲,那么不会传递任何东西给突触后神经元。

for step in range(num_steps):
    cur1 = fc1(spk_in[step]) # post-synaptic current <-- spk_in x weight
    spk1, mem1 = lif1(cur1, mem1) # mem[t+1] <--post-syn current + decayed membrane
    cur2 = fc2(spk1)
    spk2, mem2 = lif2(cur2, mem2)

    mem2_rec.append(mem2)
    spk1_rec.append(spk1)
    spk2_rec.append(spk2)

# convert lists to tensors
mem2_rec = torch.stack(mem2_rec)
spk1_rec = torch.stack(spk1_rec)
spk2_rec = torch.stack(spk2_rec)

plot_snn_spikes(spk_in, spk1_rec, spk2_rec, "Fully Connected Spiking Neural Network")

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值