刘家华,陈靖宇
广东工业大学 计算机学院,广州510006
脉冲神经网络(Spiking Neural Network,SNN)[1]是第三代人工神经网络,它结合了生物神经系统与人工神经网络的结构、功能与原理,对脑神经系统进行建模,模拟仿真人的智能行为,如学习、识别、推理演算等[2],与传统的人工神经网络相比,脉冲神经网络更接近人脑神经网络的工作机理。脉冲神经网络以脉冲神经元[3]为基本单元,脉冲神经元(Spiking Neuron)膜电位非线性累积,当到达阈值电位后脉冲放电并进入不应期冷却,脉冲通过轴突传递给下一个神经元,大量的脉冲神经元构成的神经网络不仅拥有更强大的计算能力,而且可以处理复杂的信息信号和模拟连续函数[4]。不同的神经元具有不同的几何形态和电学特性,通过对这些形态不一的神经元进行数学建模与数值分析,才能开展多种神经计算与模拟仿真。
随着神经科学研究成果的积累,早期人们对生物神经系统的构造和运行机理已有了比较全面的认识,对不同的生物神经元构建出具有生物可解释性的脉冲神经元模型。Hodgkin 等人通过对乌贼轴突神经的研究,揭示了各种可兴奋性细胞的基本规律,提出了Hodgkin-Huxley神经元模型[5]。Lapicque用电子线路模拟神经元的神经生理现象,简化了Hodgkin-Huxley神经元模型负责的高维非线性方程,提出了漏电Integrate-and-Fire 神经元模型[6]。Izhikevich 通过对Hodgkin-Huxley 神经元模型的分岔分析,结合了Integrate-and-Fire 神经元模拟的计算效率,提出了Izhikevich 二维脉冲神经元模型[7],以1 000个Izhikevich为模型的神经元在1 s的生物时间仿真1 000 生物周期。近几年来,人们对脉冲神经网络模型进行深入研究,相继提出了许多空间复杂的神经元模型,如表1 所示,BULE BRAIN 团队提出的Hippocampus神经元模型,它有13种不同形态的神经元,由约80万个神经元和3.6亿个突触连接构成。
表1 多种神经元模拟示例
庞大的神经元分布与频繁的神经元间的脉冲交互,在串行方式下难以进行仿真实验。针对这个问题,许多科研团队提出了一些解决方案。曼切斯特大学类脑科学研究团队研发了SpiNNaker 脉冲神经网络模拟器[13]。SpiNNaker 模拟器构建于sPyNNaker[14]软件层与SpiNNaker 的类脑计算机[15],支持更新神经元状态的时间驱动和脉冲处理的事件驱动,可以高效率多线程并行地模拟大规模不同模型的脉冲神经网络。NEURON为脉冲神经网络提供了一种分布式并行计算平台[16],神经元计算任务可以分布在不同的处理器节点上,以时间同步方式进行神经元仿真实验。虽然众多的模拟平台为脉冲神经网络提供了模拟环境,但国内使用权限的原因,国内研究者难以在神经科学平台上进行模拟实验。如何仅仅利用个人计算机实现脉冲神经网络高效率地模拟仿真,成为国内神经科学研究者所关注的问题之一。
随着计算机硬件的支持,计算资源的提升,个人计算机内核数不断增多(如ARM A83 处理器8 核,Intel i7-8740处理器6核),为此,本文设计了一种多核并行的脉冲神经元网络模拟器框架,利用多核的计算能力,高效地对大规模脉冲神经网络进行并行计算。在并行计算任务的分发方面,将神经元进行编码,并对每个核进行映射。在网络通信方面,采用源地址寻址的通信方式,自定义分布式路由表实现处理器内多核间的脉冲传输。采用同步时间驱动策略,在每个生物周期进行动态同步,解决并行同步问题。以Izhikevich 脉冲神经元为模型,在大规模的脉冲网络结构上进行仿真实验。实验结果表明,本文的模拟器在大规模的网络结构中,并行仿真计算的效率优于传统的串行仿真计算。
Izhikevich 脉冲神经元模型是单房室神经元,由于该模型结构简单,本文以Izhikevich 脉冲神经元模型作为模拟器仿真实验对象。在多核并行模拟器设计中,涉及到并行任务的分发、多核间的网络传输、时间同步的问题。针对这些问题,进行了神经元的映射与编码设计,自定义路由表与动态同步设计。
数学上来讲,脉冲神经元是一种混合系统:神经元的状态根据一些生物物理方程不断变化,这些方程通常是微分方程(确定性或随机性、普通或偏微分方程),通过突触接收到脉冲信号触发一些变量的变化。因此脉冲神经元的动力学可以描述如下:
其中,X 是描述神经元状态的向量,f 表示神经元状态变量演化的微分方程,gi指脉冲通过突触i 后对神经元的影响,当X ∈A 满足某个条件时就会发出一个脉冲[17]。例如Izhikevich 模型Vm≥θ(这里Vm是神经元膜电位对应矢量X)神经元产生一个脉冲,同时作为X的膜电位将被重置。Izhikevich的二维脉冲神经元模型如下所示:
如果神经元的膜电位V ≥30 mV,辅助的复位机制为:
式中,V 表示膜电位;U 表示恢复变量,用来代理生理模型中激活的K+电流和流失的Na+电流,实现对膜电位V 的负反馈。Izhikevich神经元模型中的参数a、b、c、d是无量纲参数,随着参数a、b、c、d 取值的变化,Izhikevich神经元模型可以表现出丰富的脉冲发放模式。参数a表示恢复变量U 的时间尺度,a 的值越小,表明恢复得越慢;参数b 表示恢复变量U 依赖于膜电位V 的阈值下随机波动的敏感程度;参数c 表示神经元发放脉冲后膜电位V 的复位值;参数d 表示神经元发放脉冲后恢复变量U 的复位值。
映射与编码设计思路:(1)每一个神经元总有唯一内核与它对应;(2)充分利用每个内核的计算资源,每个内核间神经元个数差不超过M ;(3)确保神经元的独立性,映射前后神经元有独立的编码。
大规模的脉冲神经网络在多核中并行计算时,需要将计算任务分发至每个内核中,即将网络中的神经元映射至对应的内核。内核的集合为C={Cm;m=1,2,…,M},M 是内核的个数,神经元的集合为V={Vn;n=1,2,…,N},N 是神经元个数。神经元与内核的映射关系可以表达为:
神经元初始分配顺序序号,神经元采用均分的方法映射至对应的内核,每个内核平均分配到的神经元个数为AVG,AVG 可以表示为:
若有多余的神经元,多余的神经元分配至最后一个内核,最后一个内核神经元个数为EXTRA,EXTRA 可以表示为:
神经元映射对应的内核后,由源序号重新编码。神经元编码定义为32 位,编码规则如下:前12 位为CPU的ID(保留12位CPU位方便以后的扩展应用),中间4位为内核ID,后16位为神经元核内局部ID,如图1所示。
图1 神经元的映射与编码
路由表设计思路:(1)根据网络拓扑结构可生成静态路由表;(2)源神经元通过查表可寻找目的神经元;(3)多表结合,减少查询的时间复杂度。
以源地址寻址作为内核间神经元的通信方式,由此在每一个内核中设计了两份路由表:(1)第一份路由表为发送表(Table 1),其作用是当本核内神经元生成脉冲,通过Table 1由源神经元ID查询到对应目的神经元ID。若目的神经元为本核内的神经元,直接根据路由表的权值影响本核目的神经元的权值。若目的神经元为核外的神经元,将脉冲(源ID)通过I/O传输方式写入对应的神经元所在的内核缓存中。(2)第二份路由表为接收表(Table 2),当本核收到来自其他核发来的脉冲(源ID),通过Table 2 查询该脉冲影响本核内的哪些神经元,并根据Table 2获取到影响权值大小。如图2所示,根据自定义的网络拓扑结构与突触连接权值生成权值文件,在神经元映射与编码后,根据权值文件生成每个内核对应的两份路由表。生成路由表的算法如下所示。
算法1 生成路由表
查表的时间复杂度为O(1),通过实验测速,源神经元查询多个目的神经元在1 μs内完成。
图2 路由表的生成
神经网络仿真有两大类算法:同步时间驱动算法[18]和异步事件驱动算法[19]。其中同步时间驱动算法所有的神经元在每一个周期都进行同步更新,异步事件驱动算法只有当神经元在接收或发出一个脉冲时才会更新。时间驱动算法与事件驱动算法在理论上相比,神经元处理时间上时间驱动算法是近似的,没有事件驱动算法精确。但考虑到模拟器是为大规模仿真而设计的,在大规模仿真中,性能是一个关键问题,由于网络延迟存在,异步驱动算法无法在精确时间内完成点对点的脉冲传输,并且无法大规模集成地对神经元群批处理。再者事件驱动算法的精度依赖于特定的神经元模型[20],存在模拟器的扩展性不高的问题。通过综合考虑,本文模拟器采用的同步时间驱动算法如下所示。
算法2 同步时间驱动
在同步时间驱动算法中,所有神经元的状态变量在每个周期进行一次更新X(t)→X(t+dt),更新所有变量后,对每个神经元检查阈值条件。每个满足该条件的神经元产生一个脉冲,该脉冲传输到其目标神经元,更新相应的变量(X ←gi(X))。
算法的仿真时间由两部分组成:(1)更新神经元状态;(2)脉冲的传播。假设神经元的数目为N ,那么时间复杂度为O(N/dt)。假如在每个生物周期中,平均有FN 个脉冲由神经元生成(F 是脉冲平均生成率),需要传播至P 个目标神经元,总时间成本为T,T 可以表示为:
这里,cu是单个神经元更新状态花费的时间,cp是单个脉冲传输所花费的时间。
动态同步设计思路:(1)内核完成每个周期计算任务与脉冲传输后进行一次状态同步;(2)以最先完成计算任务的内核时间点作为同步开始,以全部内核完成同步的时间点作为同步结束;(3)解决同步时网络延迟、脉冲数据丢失的问题。
在时间同步方面,同步分为初始同步与周期同步。初始同步:每一个内核绑定独自的线程,在每个线程中设置线程栅栏,只有当每个内核都完成本核的初始化后,打开线程栅栏使得所有线程在同一时间点开始运行。周期同步:在每个周期对每一个内核进行周期同步,如图3 所示。当一个内核完成本周期的计算任务后,通过广播的方式发送同步数据包给其他核。然后自身进入接收阶段并每隔一段时间间隔t 重复发送同步数据包(防止同步包的丢失)。t 由神经元数量N 与内核数量M 决定,可以表示为:
若本核收到其他核传来的同步数据包时,记录对应核的周期完成情况。只有当每个内核自身完成本周期的计算任务和收到其他内核的同步数据包后,则开启下一个周期。若本周期计算完成但长时间没收到其他核的同步数据包,则重新广播本核本周期的同步数据包。
图3 脉冲神经网络周期同步
内核结构如图4 所示,每个线程绑定独立的内核,内核中存放映射后的神经元,同时内核也存放对应的两份路由表Table1 与Table 2,其中Table 1 为发送表,Table 2为接收表。在共享内存上对每个核分配两块独立的内存空间,分别为缓存1(Buffer 1)与缓存2(Buffer 2)。其中Buffer 1 存放本核神经元生成的脉冲,Buffer 2 接收存放外核传来的脉冲。
模拟流程如图5所示,根据网络拓扑结构生成对应的权值文件,由权值文件创建每个核对应的路由表,根据配置参数初始化所有神经元。将每个核绑定至独立的线程,当每个核部署完成并初始同步后开始周期模拟。每个核的每个周期的主要工作分为三步:(1)更新核内每个神经元的状态,根据脉冲神经元的模型计算出神经元的膜电位,若神经元膜电位高于阈值则生成脉冲(源ID),将脉冲放置核内的缓存1(Buffer 1)中;(2)处理神经元生成的脉冲,当遍历更新完核内所有神经元状态后,查看缓存1 是否有本核神经元生成的脉冲,如果有脉冲,则逐一取出并通过查发送表(Table 1)直接影响本核内对应神经元的膜电位或将脉冲发送至对应核的缓存2(Buffer 2)中;(3)处理外核传来的脉冲,查看缓存2 中是否有外核传来的脉冲,如果有脉冲,则逐一取出并通过查接收表(Table 2)直接影响本核内对应神经元的膜电位。当每个核完成本周期的任务后,所有核进行一次周期同步。仿真模拟结束后,记录每个脉冲神经元在每个周期的生成脉冲情况。
图4 内核结构
图5 模拟仿真流程
本文的实验环境基于Intel Core i7-8750 六核处理器,内存24 GB,Liunx操作系统,GCC-version7.3版本下完成编写程序与编译。
根据Izhikevich文献[7]的模型生成相同的脉冲神经网络结构,总共有1 000个脉冲神经元,神经元之间以全连接的方式连接,神经元间的突触权值随机生成,兴奋性神经元突触权值在0~0.5 范围,抑制性神经元突触权值在-1~0范围,神经元的其余配置参数如表2所示。
表2 神经元的配置参数
图6 是Izhikevich 提供的源码在1 000 个生物周期以串行的方式模拟仿真的结果,模拟仿真时间为69 ms,脉冲激活数是7 591。图7 是在六核单处理器环境下在1 000 个生物周期以并行的方式仿真的结果,模拟仿真时间是805 ms,脉冲激活数是8 256。对比结果显示两者脉冲激活数相近,多核并行模拟器生成的脉冲激活结果图与Izhikevich 提供的实验结果图呈现出相同的alpha波段与gamma波段,验证了模拟器的理论正确性。
图6 Izhikevich原文仿真的实验结果
图7 模拟器仿真的实验结果
针对Izhikevich模型的串行计算环境与本文并行计算环境做不同数量集的对比实验,生成三种不同数量级的网络结构,分别为10 000、50 000、100 000 个Izhikevich模型的脉冲神经元网络。在10 000个脉冲神经元模型中定义8 000 个兴奋性神经元和2 000 个抑制性神经元随机分布,网络结构定义为每个神经元与10%的神经元随机连接。在50 000个脉冲神经元模型中,定义40 000 个兴奋性神经元和10 000 个抑制性神经元随机分布,网络结构定义为每个神经元与10%的神经元随机连接。在100 000 个脉冲神经元模型中,定义80 000个兴奋性神经元和20 000个抑制性神经元随机分布,网络结构定义为每个神经元与10%的神经元随机连接。配置参数与上个实验参数相同,10 000、50 000、100 000不同规模数量集的脉冲神经网络在1 000个生物周期在模拟器上所花费时间如图8~图10所示。
图8 10 000神经元不同核的模拟时间
图9 50 000神经元不同核的模拟时间
图10 100 000神经元不同核的模拟时间
在多核并行模拟器下成功复现了1 000个Izhikevich神经元模型的脉冲网络,在此基础上进行10 000、50 000、100 000个神经元的脉冲网络的模拟对比实验。
仿真设计及实现并行模拟的目的是希望并行模拟比相应的串行模拟更快,为了评估并行计算对仿真模拟效率的提高,通常用加速比[21](Speedup)作为衡量标准,加速比S 可以表示为:
其中,Te为串行程序模拟时间,Tp为并行程序模拟时间。仿真结果如表3所示。
表3 不同规模的并行计算加速比
从表3可以看出,多核并行计算在规模较小的数据集上(10 000数量以下的神经元)效率不如串行计算,但在大规模数据集上并行计算可以提高仿真速度,最大加速比为1.96,当内核达到一定数量时,加速比逐渐收敛。如图11 所示,本实验中当内核数量达到4 核后,内核数量越多并行计算的效率却得不到更好的提高。
图11 不同规模数据集的模拟情况
本文在10 000与50 000数量集的实验中,记录每个阶段花费的时间,如表4 所示,模拟时间开销主要在神经元状态的更新与脉冲的传输。在10 000数据集中,神经元整体状态更新所花费时间与内核间脉冲传输的时间比为230。在50 000 数据集中,神经元整体状态更新所花费时间与内核间脉冲传输的时间比为516。
表4 各阶段的时间开销
在多核间的网络传输中,采用共享内存的方式实现多核间的数据传输,共享内存是数据共享的最快方式,但多线程之间的数据传输需要对缓存区提供互斥条件。当内核外神经元交互频繁时,多个线程容易同一时刻对同一个缓存区进行访问而出现线程阻塞的情况,由此导致网络出现延迟的情况。
综上分析,当核内计算量不繁重,内核的平均计算速度远快于网络传输速度时,并行计算效果不如串行计算。当内核平均计算速度接近网络传输速度时(大规模计算下),并行计算速率优于传统的串行计算。而在大规模计算下,网络传输交互频繁时,内核越多,周期计算效率不一定得到有效的提高。
面对大规模的脉冲神经网络模拟,一般研究者在个人计算机上以串行的方式难以高效率地进行模拟仿真,本文设计一种多核并行脉冲神经网络模拟器,为脉冲神经网络提供一个多核并行计算的模拟环境。在大规模神经网络模拟中,模拟器可以充分利用每个内核的计算资源,高效率进行脉冲神经网络的模拟。实验结果表明,本文设计的模拟器与传统的串行仿真模拟相比,在大规模数据集的并行计算环境下,速度约为串行计算的两倍。本实验也可以为类似的脉冲神经网络的模拟并行化设计提供参考。
在本文实验中发现,当内核数达到一定数量时,加速比将逐渐减少,后续的工作中,可以设置多级缓存,减少多核间的网络传输延时。同时还发现,当内核间的神经元交互频繁时,网络传输效率不高,在后续工作中,可优化神经元的映射算法,将交互频繁的神经元映射至同一内核中,减少网络传输的负载。在未来的工作中,增添模拟器的接口模拟,以便不同的脉冲神经元模型都可以在模拟器上并行模拟计算。