4. 脉冲学习

为了在脉冲神经网络(SNN)中实现学习能力,与所有类型的神经网络一样,需要更新神经元之间的权重。正如您可能知道的,要应用梯度下降和反向传播等流行算法,需要使用平滑可微的函数。

然而,脉冲神经元不具备平滑的激活函数(脉冲要么发生要么不发生)。本页面旨在以通俗易懂的方式解释——尽管SNN具有不可微分的特性,我们如何在Norse中训练它们。更详细的方法描述可参阅Emre O. Neftci, Hesham Mostafa和Friedemann Zenke的著作。

不过在继续阅读之前,请确保您熟悉 PyTorch 如何与Autograd和反向传播配合工作。 Norse基本上应用了相同的原理。

4.1. 训练脉冲神经网络

为解决这一问题,人们尝试了许多方法,效果参差不齐。这里我们仅讨论替代梯度方法,并展示如何在norse中实现它。

我们的方法基于Steven K. Esser等人提出的SuperSpike方法(用于快速、节能神经形态计算的卷积网络),并在Friedemann Zenke和Surya Ganguli的研究中得到了进一步阐述。

神经元的工作原理是通过来自突触前神经元的输入电流来更新其膜电位方程。 如果输入电流超过阈值,突触后神经元就会释放一个脉冲。 这可以很容易地用代码表示:

if membrane > threshold: spike!

然而,当你对其求梯度时会发生什么?在大多数情况下梯度会为零,因为membrane < threshold,这意味着神经元对输出完全没有影响。但有时电流会超过阈值,这时就会产生激活,梯度也随之改变!为了解决这个问题,我们可以"假装"梯度没有这种突兀的突变。相反,我们可以观察神经元的数值状态,并将其作为衡量神经元对输出影响程度的指标。

给定神经元膜电位(\(U\))和神经元放电阈值(\(v\)),这是某个激活函数(\(\sigma\))的SuperSpike替代偏导数的简化版本:

\[\sigma '(U_i) = \left(1 + |U_i - v| \right)^{-2}\]

In the SuperSpike algorithm, we look at the difference between the neuron membrane and the firing threshold. If, say, the neuron membrane voltage is much higher than the firing threshold, we know that the neuron will fire. But too far away from that threshold indicates that the contribution of the neuron is unimportant because it would require a large modification to that particular neuron to not impact the output.

相反,如果神经元膜电压远低于阈值,该神经元很可能不会触发,梯度贡献同样较低。

就这样!SuperSpike 允许计算不可微分函数的梯度。这反过来又让我们能够利用 PyTorch 原生的自动微分特性。

在Norse中实现的SuperSpike算法可以在threshold.py模块中找到。