极简的神经网络
作者: 陈凯
摘要:本文提出了一种用相当简短的Python代码实现的基于离散信号的神经网络框架,介绍了如何借助MemBrain软件的神经网络自主学习所生成的数据,来为这个简单的神经网络框架设置参数,使之成为可运行的神经网络模型,并介绍了如何将这个框架用于实现具有一定的探索性、趣味性的教学实验。
关键词:神经网络;人工智能;教学实验
神经元负责处理和传递信息,大脑中的神经元以离散的方式进行工作。神经元细胞膜的两侧存在电位差,称为膜电位,当神经元接收到足够的兴奋性刺激时,细胞膜上的离子通道会打开,使细胞内外离子的分布发生变化,这种变化会导致膜电位迅速变化,形成一个电脉冲,这个电脉冲沿着神经元的轴突传播。当某神经元接收到来自其他神经元的电信号后,根据输入信号的强度调整自身的膜电位,产生相应的输出信号。电脉冲一旦产生,其幅度和形状在传播过程中基本保持不变,不会因为刺激的强弱而改变,电脉冲的强度主要体现在频率上,即单位时间内电脉冲产生的次数,频率越高,传递的信息强度就越大。在神经网络工作过程中,神经元并不是单纯的单向传递信号,而是存在着复杂的相互作用,其中,抑制性神经元是一种能够降低其他神经元活动水平的神经元,当抑制性神经元受到刺激并产生电脉冲时,会释放抑制性神经递质,降低神经元接收信号的强度。
以上文字主要由某人工智能语言工具生成,笔者略微做了一些整理。人的大脑的神经网络中的神经元处理的是离散的信号,但它在被激发后的信号发送时,又通过某种频率来产生出一种能模拟特定信号强度的效果。根据人脑神经网络的工作情况,可以设立这样的一种神经网络模型:每个神经元只用“0”和“1”两种数字表示,分别代表静息和兴奋两种状态,而被激发为兴奋状态的神经元,则用某个“-1”到“1”之间的浮点数来代表电脉冲频率强度,其中的负数代表抑制信号,正数代表加强信号。本文给出的案例试图将二进制数编码、数据处理、算法等教学内容与神经网络的教学内容融合在一起,带领学习者利用已学习到的基础算法及程序代码的知识和技能,搭建简单的软件模型来模拟人脑神经网络的运作过程,这样就实现了一种学科内的知识和技能的整合。
实现异或逻辑运算的极简神经网络
首先,以非线性函数异或逻辑运算的实现为目标,来构建神经网络。该神经网络由两个输入层神经元、两个隐藏层神经元和一个输出层神经元组成。其输入层神经元用列表I表示,Python代码为:
I=[0,1] # 或[0,0],[1,0],[1,1]
隐藏层神经元用列表L表示,其中“Lr0”和“Lr1”是两个等待着按特定规则对输入层神经元数据进行处理并获取到值的变量,Python代码为:
L=[Lr0,Lr1]
输出层神经元用列表O表示,其中“Or0”是等待着按特定规则对隐藏层神经元数据进行处理并获取到值的变量,Python代码为:
O=[Or0]
隐藏层或输出层神经元按规则获取数值的代码也很简单,每个神经元的数值都只需要一句代码,用来实现根据设定的阈值确定是否兴奋的功能,被激发为兴奋的神经元则输出特定的电脉冲强度,如下面的代码表示当来自两个输入层神经元的信号总强度超过1.25时激发为兴奋并输出电脉冲强度为1,Python代码为:
Lr0="1 if (I[0]+I[1])>1.25 else 0"
该神经网络的完整程序代码及对应代码功能的可视化结构图可参见图1。若不算上输入和输出,只有9行程序代码,堪称极简。但哪怕是这样简单的代码,也能够体现出神经网络解决问题的完整流程,这里将其称为Python的极简神经网络框架。
自主学习的神经网络四像素图片的0或1的识别
有了用神经网络实现异或逻辑运算的经验,可以试着搭建稍微复杂一些但功能也稍微有趣一些的神经网络。例如,有一个包含了1到4号的四个输入神经元、5到7号的三个隐藏层神经元、12到14号的三个输出神经元组成的神经网络(这里序号不连续,是另有用意,后文会说明),其中,输入层神经元是“0”或“1”的二进制数据,输出层神经元是在“-1”到“1”之间变化的数字。
这个神经网络的功能是检测四个像素的单色图像更像0还是更像1,假如运算结果中12号神经元数值最大,则表示图像既不像“0”也不像“1”,如13号神经元数值最大,则表示图像最像“0”,如14号神经元数值最大,则表示图像最像“1”。例如,当输入的是“0”“1”“0”“1”时,整体图案看上去更像“1”,14号神经元最兴奋,数值最大。四像素图对应“0”“1”“0”“1”输入信号时的形态以及神经网络的可视化结构如图2所示。
接下来,最大的难题是如何为输入层和隐藏层神经元设置输出权重,以及如何为隐藏层和输出层神经元设置被激发为兴奋状态的阈值。尽管这个神经网络从图示看还是相当简单,但总共涉及21个输出权重值数据和6个阈值数据,如果只靠人脑来推测设定,就相当困难了。这时,就需要依靠计算机算法,在与预定规则目标的对比过程中,通过反向传播来调整神经元参数,这就是神经网络的自主学习过程。具体的参数调整过程涉及梯度下降的数学方法,对于数学水平有限的学习者,可以暂且将数学运算过程封装成为黑箱,只观察每一次数学运算对权重值数据和阈值数据调整迭代的效果。
有多款不同的软件可以将神经网络自主学习过程可视化地显现出来,这里推荐的是MemBrain软件,之前所给出的神经网络可视化效果图也是由该软件生成的。MemBrain软件的基本使用方法,可参考《神经网络自己搭》(本刊2019年第19期刊发的文章),这里就不再赘述了。为了能更贴近人脑神经网络工作原理,在搭建神经网络时,需要将隐藏层神经元设置为“BINARY”类型,使之仅能表现为非“0”即“1”的离散的状态;将输出层神经元设置为“IDENTICAL”类型,用以对应人最终感受的连续性。
在进行自主学习前,首先要设定作为学习目标的输入神经元和输出神经元的对应规则,这个规则可以从CSV文件导入,如图3所示的CSV文件设置了四条规则,虽然说,四个输入神经元可以有十六种变化形式,但除了必要的目标,并不需要将全部规则都作设定,神经网络自身可以很好地处理模糊的输入数据(可以试着输入一个不在规则内的数据并观察神经网络运行结果)。
神经网络经过自主学习后,得到可供参考的权重值数据和阈值数据,由于学习开始时的起始数据是随机生产的,所以每次自主学习的结果都是不同的,图4所示的是某次自主学习的结果,同样是用CSV文件表示的。
然后,就可以将数据写入Python的极简神经网络程序框架,如图5所示。可以看出,尽管神经元增加了,但程序仍然非常简短。实际上,只要是由一个输入层、一个隐藏层、一个输出层组成的神经网络,神经元的数据就都只要在相应层的列表中设定,不需要改变程序的框架结构。接下来,是将MemBrain自主学习生成的数据写入程序框架中(当然可以另编代码,将MemBrain自主学习生产的数据自动生成为列表数据)。完整的程序代码如图5所示。
从逻辑推断到模拟仿真
在实验中可以发现,刚才这个神经网络的学习能力并不强,每次在自主训练后,神经网络常常只能正确实现四个预定规则目标中的两个或三个。例如,上页图5所示的神经网络的程序代码能够正确判断“0”“0”“0”“0”为无效数字,“1”“1”“1”“1”为数字0,“0”“1”“0”“1”为数字1,但在判断“1”“0”“1”“0”时却将其判定为数字0,与预设规则不符。那么,如果在神经网络中增加神经元,能否让学习效果变得更好呢?
图6所示的是额外增加四个神经元到隐藏层中的神经网络结构图示,这样就用到从1号到14号连续编号的共14个神经元组成为神经网络。多次实验可以发现,神经网络的学习情况仍然不理想,添加神经元的效果非常有限。
然而,若将新增加的四个神经元设置成一个新的隐藏层,如图7所示,神经网络的学习能力就得到了明显的提升,虽然有时候预定规则目标仍然不能达成,但稍许训练几次,就能生成达成所有四条预设规则目标的参数了。关于如何合理地假设神经网络结构才能得到更好的自主学习效果,可以组织成为让学习者自主探索的实验活动。
有多个隐藏层的神经网络,比只有单层隐藏层的神经网络有更强大的函数学习能力。然而,如果不是利用计算机的反复迭代,人的头脑很难通过单纯的逻辑推断,来确定略微复杂一些的神经网络中神经元的被激发兴奋阈值以及输出权重值(至少笔者认为自己是难以仅靠逻辑推理作出推断的)。从这里可以引出一个有趣的推论,如果人脑的神经网络的工作过程的确和计算机的神经网络工作过程相似,那么就会存在这种情况,尽管头脑可以做出正确的判断,但仅凭自己的逻辑思考,还是难以知道自己究竟是如何做出这样的判断的,这也暗示了,人的所谓的直觉也好,“只可意会,难以言传”也好,其实都是有物理上的依据的。人造的神经网络提示了真正人脑工作原理的一种可能性,当然也引出了更多有趣的问题,如若能将人造的神经元补充到人的头脑中,是否就能使得人的智能得到提升,或者用以治愈阿尔兹海默症等?当人造的神经元占据人脑的主导地位时,这个人是否仍然是原来的自己?人的所谓的“自我意识”是否就是一种由底层神经元计算模拟出来的“幻觉”?这些问题在当前自然还不会有明确的答案,但这些未知无疑能促使大家更多地去思考,去探索。
参考文献:
陈凯.神经网络自己搭[J].中国信息技术教育,2019(19):25-27.