
SAST weekly 是由电子工程系学生科协推出的科技系列推送,内容涵盖信息领域技术科普、研究前沿热点介绍、科技新闻跟进探索等多个方面,帮助同学们增长姿势,开拓眼界,每周更新,欢迎关注!欢迎愿意分享知识的同学投稿至 [email protected] , 期待你的作品!
神经网络的地位在当今的人工智能领域毋庸置疑,但凡想搞点什么事情,比如做个图像识别(尤其是媒认大作业),整个AlphaGo来下棋之类的,都是离不开神经网络的。事实上,这里的“神经网络”,所指的主要是人工神经网络(ANN)——当今最普遍的一类神经网络。今天想讲的,是另一类非常有潜力的神经网络,即脉冲神经网络(SNN)。
01
人工神经网络
在讲脉冲神经网络之前,还是来对人工神经网络做个概述方便之后进行对比。
人工神经网络的范畴是非常广泛的,许多耳熟能详的名词,什么深度学习、卷积神经网络、循环神经网络等等,都可以归属于这一范畴内。
而各种人工神经网络的工作原理以及训练方式也是大同小异的:
大体上来说,就是用一层层的网络堆积起来形成一个总体的网络,每层网络以某种方式获得自己的输入,并将这一输入进行一些处理之后再发送给自己的下一层,直到最终到达输出层。而每一层之间对数据进行的处理也是比较类似的,基本可以表述为
y=f(Wx+b)
的形式,x为输入,W是一个矩阵,f是一个非线性函数,总的来说就是一次线性变换+一次非线性变换,不同网络之间的不同之处只在于这个输入“x”的来由,有些取上一层的输出以及前几层的输出合起来作为输入;有些取上一层的输出和自己前一次的输出作为输入,等等。
神经网络的本意就是模拟人脑神经工作原理的网络,人工神经网络是我们在这个方向上踏出的重要的一个步骤,可惜它在模拟人脑工作这一方面,仍做得并不完美。
02
脉冲神经网络
我们将人工神经网络中的每层中的每个节点都看作一个神经元,那么这每个神经元在工作时都干了些什么呢?其实无非也是接收输入→线性变换→非线性函数→输出。但回想一下高中生物的知识,我们脑中的神经元是这样工作的吗?不是,我们的神经元不知道啥是非线性函数,也不会真的去做矩阵乘法运算,而是通过“兴奋”机制进行工作的:每个神经元从前几个神经元处获取信号,这些信号能对这个神经元的电位产生影响,或提升或降低,当电位超过一定阈值的时候神经元即产生“兴奋”,而后对自己的“下家”发送电信号,在兴奋一段时间之后,如果自己的上家没有持续发送令自己兴奋的信号,就会逐渐回归抑制的状态。
于是,模仿这种兴奋机制,今天的主角:脉冲神经网络就随之产生了。相比于人工神经网络,每个神经元进行的是由输入到输出的计算,在脉冲神经网络中,每个神经元在接收输入信号之后进行的是对自己电位状态的运算(如图)。
每个神经元在抑制状态时具有一定的初始电位以及一个高于初始电位的阈值。在受到刺激(前置神经元输出1)之后,一般来说这个电位的值就会陡增,当自身电位超过阈值之后,该神经元即兴奋(输出1),兴奋一段时间,电位下降回到阈值之下(输出变为0),并最终回到初始电位。
于是,脉冲神经网络与人工神经网络的最大差别出现了:对于人工神经网络,每个神经元接收与发出的是与同一时刻到达/发送的一批数据,而对于脉冲神经网络,接收的是脉冲信号,信号改变电位,再根据自身电位同样发出脉冲信号。
如果单从对人类脑神经的模拟程度上来看,似乎这个脉冲神经网络学得更加像一些?
03
SNN的优劣
SNN比之ANN更接近人脑的工作机制,自然也就带来了相应的优势,其中最重要的一点就是对时间信息的利用。
很多人工神经网络对时间信息都是没有涉猎的,比如卷积神经网络等,其输出仅取决于当前输入。在我的有所了解的网络结构中,有循环神经网络(RNN)对时间信息有所利用——将前一时刻的输出作为下一时刻的输入,使得网络多了一些记忆性。
而SNN对时间的利用显得更为的自然,是以神经元电位状态的形式对前一时刻的信息进行保存的,当前时刻的状态由前置神经元给出的刺激信号和前一时刻的电位状态决定,而当前输出由当前状态决定。这种方式从感觉上比较类似于状态机的工作方式,无疑比之RNN对时间信息利用地更为自然(如下图,受到刺激后,电位提高,在之后逐渐随时间衰减,再受到刺激时,电位变化累加在当前状态上,直到电位超过阈值后进入兴奋状态)。
然而,脉冲神经网络如今却并没有普及,人工神经网络仍然是神经网络中的主流,这是因为脉冲神经网络仍有其缺点,最重要的缺点在于其训练过程——由于脉冲神经网络中输入、输出都是脉冲信号,而脉冲信号本质上可看成二进制比特流,这东西理论上是无法求导的,也就没法直接套用ANN使用的BP算法进行训练。
而时至今日,还没有专为SNN开发的算法让它能够进行监督学习。如今已有的训练方式,如STDP算法,都是无监督训练的算法。当前来说,对脉冲神经网络进行监督训练,一种途径是,对脉冲神经网络进行适当的改变,使其具有一些ANN的特性,从而能够进行求导并应用BP算法。
04
实战训练
最后,我们来尝试通过SNN来完成一些比较简单的任务——比如通过MNIST数据集训练手写数字识别。
训练一个网络,最重要几个因素,无非是网络结构、激活函数、损失函数等。
(注:以下代码来源于我上学期上过的一门课“类脑计算系统技术”)
网络采用较简单的三层结构(784-512-10)。
首先将输入的模拟信号(图像的灰度,取值范围为0-1)转化为脉冲信号(采用占空比的形式,如灰度0.3,即在一段时间中输出30%的1和70%的0),用脉冲信号取刺激第一层的神经元,第一层神经元输出对应的脉冲信号,继续刺激第二层的神经元,第二层神经元再输出脉冲信号即传到输出端口。而对于每个神经元,都首先根据刺激更新电位状态,而后根据状态进行输出(输出同样为脉冲信号,按照占空比转化为具体数值)。
如图即为激活函数,激活函数是是的SNN能够套用BP算法的关键,标准的激活函数应当为一个阶跃函数(超过阈值为1,不到则为0),但这样其导数将是一个δ函数,难以进行误差反向传播,于是,这里对激活函数做如下图的近似:
这样,可以进行求导了,也就可以应用BP算法了。
有了以上的网络结构,就可以开始训练了,选取损失函数为均方误差nn.MSELoss(),优化器选择Adam,在mnist上训练的效果如下:
从上至下依次为测试集准确率、训练集Loss、测试集Loss(mnist较简单,只训了10个epoch意思意思)。
来看看识别效果:
(下面是手写数字图片,上面的标题为识别出的数字,做得比较简陋)
对SNN的基本介绍差不多就到这里,希望能帮助大家认识这种新型的,与众不同的神经网络。
撰稿:邹俊泓
审核:孙志尧