脉冲神经网络 SNN

第三代神经网络 SNN

尖峰神经网络(SNN,Spike Neural Network)是一种神经网络模型,它在模拟人脑处理信息方式方面比传统的人工神经网络更为接近。 SNN 的独特之处在于其神经元之间的交流是通过“尖峰”(Spike),即短暂的电信号脉冲来实现的,类似于生物神经元的通信方式。这种方式允许 SNN 以一种高效的时间编码方式处理信息,使得网络能够响应快速变化的输入信号并在更低的功耗下运行。

如下图,这这是一项由 J. Krüger 和 F. Aiple 在 1988 年进行的集中在猴子的视皮层下层的神经元之间的相互作用的研究。研究通过使用多个紧密排列的微电极记录尖峰并分析交叉相关图,旨在理解这些皮层层次中神经元的交互作用及其相关结构。其中两条竖线标记了 100ms 的间隔。

SNN 通常被视为第三代神经网络模型,它在模拟神经元动态行为、处理时间序列数据以及学习时空模式方面表现出独特优势。由于其生物学上的真实性和能效高的特点,SNN 在神经形态计算领域尤为受到关注。神经形态计算旨在模仿人脑的处理方式,开发出更高效的计算模型和硬件架构。

神经元

相比第二代神经网络,也就是基于传统的线性变换和非线性激活函数的 ANN 而言,SNN 将激活函数替换成了一种动态的时序敏感的神经元(Neuron)

基本特性
  1. 脉冲机制:SNN 神经元通过尖峰进行通信。这些脉冲是离散的事件,通常在模拟神经元的电压达到某个阈值时发生。
  2. 时间动力学:SNN 神经元具有显著的时间动力学特性。它们的状态不仅取决于当前的输入,还取决于历史输入的积累效应,这是通过内部状态变量(例如膜电位)来实现的。
  3. 生物学上的仿真性:SNN 更贴近于模拟真实生物神经系统的方式。它们试图通过模拟生物神经元的动态特性(如脉冲编码和神经元的时变动态)来处理信息。

接下来我们以两种神经元为例,讲解其工作原理。

IF 神经元

IF 神经元(Integrate-and-Fire Neuron)是脉冲神经网络(SNNs)中最基本的神经元模型之一。它的设计模拟了生物神经元的基本行为,特别是如何积累输入信号,并在达到特定阈值时产生脉冲。

积分(Integrate):IF 神经元首先会积累其输入信号。这些输入可能来自网络中的其他神经元,或者是外部的刺激。积分过程实际上是对输入信号(通常是电流)随时间的累加,这在生物学上对应于神经元膜电位的变化。 \[ U_i^{(l)}(t) = U_i^{(l)}(t - 1) + RI_{i}^{(l)}(t) \] 这里 \(U_i^{(l)}(t)\) 表示 \(t\) 时刻神经元的膜电位,\(RI_i^{(l)}(t)\) 表示 \(t\) 时刻该神经元接收的输入信号的大小,其中 \(I_i^{(l)}(t)\) 表示输入电流,由 \(t\) 时刻神经元接收到的尖峰累加而成,\(R\) 在这里表示膜电阻。

触发(Fire):当积累的信号(即膜电位)达到特定的阈值时,神经元会发射一个脉冲,并且将这个信号传递给其它神经元。发射脉冲后,神经元的膜电位通常会被重置到一个较低的初始值,准备接受下一轮的信号积累。 \[ S_i^{(l)}(t) = \Theta(U_i^{(l)}(t) - U_{\text{threshold}}) \]

\[ U_i^{(l)}(t) := U_{\text{rest}}\ \ \text{if}\ \ U_i^{(l)}(t) \geq U_{\text{threshold}} \]

这里 \(\Theta(\cdot)\) 表示阶跃函数,\(U_{\text{threshold}}\) 表示阈值电压,\(U_{\text{rest}}\) 表示静息电压。

可视化

如下图,假设 IF 神经元 15 个时刻的输入信号大小为:[0.2, 0, 0, 0, 0, 0.79, 0.02, 0, 0, 0, 0.9, 0, 0, 0, 0.09, 0.01]

膜电位在 t = 6t = 15 时达到阈值并迅速恢复到静息电位,同时神经元的后端突出释放尖峰。

LIF 神经元

LIF(Leaky Integrate-and-Fire)神经元是脉冲神经网络(SNNs)中的一个重要和常见的神经元模型。与最简单的 IF(Integrate-and-Fire)神经元模型不同,LIF 模型增加了对生物神经元电位衰减特性的模拟,使之更贴近真实的生物神经元行为。

其微分方程形式表示如下: \[ \tau_{\text{mem}} \frac{dU_{i}^{(l)}}{dt} = -(U_i^{(l)} - U_{\text{rest}}) + RI_{i}^{(l)} \]

其中 \(\tau_{\text{mem}}\) 是膜时间常数,它决定了膜电位因泄漏而衰减的速率。

可视化

如下图,假设 LIF 神经元 20 个时刻的输入信号大小为:[0.9, 0, 0, 0, 0.9, 0, 0, 0, 0.9, 0, 0.9, 0, 1.5, 0, 0, 0, 0, 0, 0, 1.5, 1.5]

该 LIF 神经元在 t = 20 时被触发。

前向传播

许多时序神经元在一起就组成了一个完整的 SNN 网络模型,以尖峰组成的时序编码信息在不同神经元之间的突触(Synapse)上进行传播。如下图所示:

对于一个全连接网络而言,第 \(l + 1\) 层第 \(i\) 个神经元而言,其 \(t\) 时刻的输入电流大小满足: \[ I_i^{(l + 1)}(t) = \sum_j w_{ji} S_{j}^{(l)}(t) = \sum_{j \in E^{(l)}(t)} w_{ji} \] 其中 \(w_{ji}\) 表示该神经元每个后突触的权重,\(E^{(l)}(t)\) 表示 \(t\) 时刻第 \(l\) 层触发的神经元的集合。

梯度替代

在 SNN 中,由于脉冲的二进制特性(神经元要么发射脉冲,要么不发射),这导致了神经元激活函数的不连续性,使得传统的梯度反向传播方法不适用。

为了解决这个问题,研究者们提出了“梯度替代”(Surrogate Gradient)方法。这个方法的核心思想是用一个连续可微的函数来近似原本不连续的激活函数的导数。这个近似的函数被称为“替代梯度”或“伪梯度”。梯度替代的步骤通常包括:

  1. 前向传播:在网络的前向传播过程中,使用真实的脉冲激活函数。
  2. 反向传播:在计算梯度并进行反向传播时,将不可微的激活函数替换为可微的替代梯度函数。
  3. 参数更新:使用这些近似梯度来更新网络的参数。

这种方法的一个常见例子是在 SNN 中使用 Heaviside 阶跃函数作为激活函数,该函数在脉冲发射时是不可微的。为了进行梯度反向传播,研究者们可能会使用 Sigmoid 函数或是带有平滑过渡的阶跃函数来近似 Heaviside 函数的导数。

简单案例

接下来我们将使用 SpikingJelly 框架 实现一个 SNN 全连接识别 Fashion-MNIST 衣物的简单案例:

导包

1
2
3
4
5
import torch
from torch import nn, optim
from torch.nn.functional import one_hot
from torchvision import datasets, transforms
from spikingjelly.activation_based import layer, neuron, surrogate, functional, encoding

模型定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class SpikingCNN(nn.Module):
def __init__(self, use_cupy: bool = False):
super(SpikingCNN, self).__init__()
self.conv_block1 = nn.Sequential(
layer.Conv2d(in_channels=1, out_channels=32, kernel_size=5, bias=False),
layer.BatchNorm2d(num_features=32),
neuron.LIFNode(surrogate_function=surrogate.ATan()), # 使用反正切函数作为代替梯度计算
layer.MaxPool2d(kernel_size=2)
)

self.conv_block2 = nn.Sequential(
layer.Conv2d(in_channels=32, out_channels=64, kernel_size=5, bias=False),
layer.BatchNorm2d(num_features=64),
neuron.LIFNode(surrogate_function=surrogate.ATan()),
layer.MaxPool2d(kernel_size=2)
)

self.conv_block3 = nn.Sequential(
layer.Conv2d(in_channels=64, out_channels=128, kernel_size=4, bias=False),
layer.Flatten()
)

self.proj = nn.Sequential(
layer.Linear(in_features=128, out_features=10, bias=False),
neuron.LIFNode(surrogate_function=surrogate.ATan())
)
functional.set_step_mode(self, step_mode='m')
if use_cupy:
functional.set_backend(self, backend='cupy')

def forward(self, x):
x = self.conv_block1(x)
x = self.conv_block2(x)
x = self.conv_block3(x)
x = self.proj(x)

return x

加载数据集

1
2
3
4
5
6
7
8
9
10
11
12
train_dataset = datasets.FashionMNIST(
root='data',
train=True,
transform=transforms.ToTensor(),
download=True
)
val_dataset = datasets.FashionMNIST(
root='data',
train=False,
transform=transforms.ToTensor(),
download=True
)

由于 SNN 接收的信号是尖峰组成的时序编码,所以我们还需要一个编码器将静态的图片(\(C \times H \times W\))转化为时序尖峰信号(\(T \times C \times H \times W\)),这里我们使用泊松编码器(Poisson Encoder)。泊松编码器认为图像每个像素的尖峰发射事件服从泊松分布,其强度 \(\lambda\) 与像素强度相关。

1
encoder = encoding.PoissonEncoder(step_mode='m')

如下图,这是数据集某个标签为衬衫的单通道图片转化为时序尖峰信号的可视化效果:

训练超参设定

1
2
3
4
T: 32 # 时间序列长度
num_epochs: 32
batch_size: 32
lr: 1e-4

训练结果可视化

STDP 学习

STDP(Spike-Timing-Dependent Plasticity,时序依赖性可塑性)是一种在生物神经系统中发现的神经元之间连接强度调整的机制,也被广泛应用于 SNN 中。STDP 是一种启发自生物学的学习规则,它根据输入和输出神经元的脉冲时序来调整突触权重。

在 STDP 中,突触的强度调整依赖于前后神经元的脉冲发放时间差。具体来说:

  1. 前突触先于后突触发放:如果一个神经元(前突触)的脉冲发放早于它所连接的另一个神经元(后突触),突触的强度会增加(Long-Term Potentiation,LTP)。这种增强反映了一种因果关系,即前突触的活动似乎是导致后突触活动的原因。

  2. 后突触先于前突触发放:相反,如果后突触神经元先于前突触神经元发放脉冲,突触的强度会减弱(Long-Term Depression,LTD)。这种削弱意味着前突触的活动与后突触的活动之间没有直接的因果联系。

数学描述\[ \Delta w = \begin{cases}{} \ A_+ \text{exp}(-\frac{\Delta t}{\tau_+}) & \Delta t > 0 \\ \ -A_- \text{exp}(\frac{\Delta t}{\tau_-}) & \Delta t < 0 \end{cases} \] 这里 \(\Delta t\) 表示脉冲时间差,满足:\(\Delta t = t_{\text{post}} - t_{\text{pre}}\),其中 \(t_{\text{post}}\) 是后突触神经元发放脉冲的时间,\(t_{\text{pre}}\) 是前突触神经元发放脉冲的时间。\(A_+\)\(A_-\) 都是正常数,表示突触权重增加或减少的幅度系数。

如果 \(\Delta t = 0\) 呢?

实际上,由于生物神经元的动态特性和噪音,完全同步的脉冲在生物神经系统中极为罕见。因此,在许多 STDP 研究和实际应用中,\(\Delta t = 0\) 这种极端情况通常不是主要关注的焦点。

STDP 是一个动态的过程,它允许神经网络通过经验学习和适应。在 SNN 中,这种机制可以用来捕捉和处理时序信息,使得 SNN 在处理类似于生物神经系统的时序依赖性任务时更加有效。

STDP 与传统深度学习中的学习规则(如反向传播)有本质的不同。STDP 依赖于局部的时序信息而不是全局的误差信号,这使其在某些方面更接近生物神经系统的学习方式。STDP 的这些特性使其在模仿生物神经系统方面具有潜力,尤其是在处理时序数据和进行无监督学习方面。


脉冲神经网络 SNN
https://goer17.github.io/2024/01/26/脉冲神经网络-SNN/
作者
Captain_Lee
发布于
2024年1月26日
许可协议