第03章-单层感知器与线性神经网络
3.1生物神经网络
人工神经网络ANN的设计实际上是从生物体的神经网络结构获得的灵感。生物神经网络一般是指生物的大脑神经元,细胞,触电等组成的网络,用于产生生物的意识,帮助生物进行思考和行动。
神经细胞构是构成神经系统的基本单元,简称为神经元。神经元主要由三部分构成:①细胞体;②轴突;③树突。如3-1图所示
每个神经元伸出的突起分2种,树突和轴突。树突分支比较多,每个分支还可以再分支,长度一般比较短,作用是接受信号。轴突只有一个,从细胞体的一个凸出部分伸出,长度一般比较长,作用是把从树突和细胞表面传入细胞体的神经信号传出到其他神经元。轴突的末端分为许多小支,连接到其他神经元的树突上。
大脑可视作为1000多亿神经元组成的神经网络。神经元的信息传递和处理是一种电化学活动。树突由于电化学作用接受外界的刺激,通过胞体内的活动体现为轴突电位,当轴突电位达到一定的值则形成神经脉冲或动作电位;再通过轴突末梢传递给其它的神经元。从控制论的观点来看,这一过程可以看作一个多输入单输出非线性系统的动态过程。
3.2单层感知器
3.2.1 单层感知器介绍
受到生物神经网络的启发,计算机学家Frank Rosenblatt在20世纪60年代提出了一种模拟生物神经网络的的人工神经网络结构,称为感知器(Perceptron)。图3.1为单层感知器结构图。
图中x1,x2,x3为输入信号,类似于生物神经网络中的树突。
w1,w2,w3分别为x1,x2,x3的权值,它可以调节输入信号的值的大小,让输入信号变大(w>0),不变(w=0)或者减小(w<0)。可以理解为生物神经网络中的输入阻碍,树突的信号不一定是100%传递到细胞核的,可能某些树突的信号有80%传递到细胞核,某些树突的信号有50%传递到细胞核,某些树突的信号被完全阻碍。
公式
表示细胞的输入信号在细胞核的位置进行汇总
,然后再加上该细胞本身自带的信号b,b一般称为偏置值(Bias)。
f(x)称为激活函数,可以理解为信号在轴突上进行的变化。在单层感知器中使用的激活函数是sign(x)激活函数。该函数的特点是当x>0时,输出值为1;当x=0时,输出值为0,;当x<0时,输出值为-1。sign(x)函数图像如图3.2:
y就是
,为单层感知器的输出结果。
3.2.2单层感知器计算举例
假如有一个单层感知器有3个输入x1,x2,x3,同时已知b=-0.6,w1=w2=w3=0.5,那么根据单层感知器的计算公式
我们就可以得到如图3.3计算结果。
x1=0,x2=0,x3=0:
x1=0,x2=0,x3=1:
x1=0,x2=1,x3=0:
x1=0,x2=1,x3=1:
x1=1,x2=0,x3=0:
x1=1,x2=0,x3=1:
x1=1,x2=1,x3=0:
x1=1,x2=1,x3=1:
3.2.3单层感知器的另一种表达形式
单层感知器的另一种表达形式如图3.4。
其实这种表达形式跟3.2.1中的单层感知器是一样的。只不过是把偏置值b变成了输入w0×x0,其中x0=1。所以w0×x0实际上就是w0,把
公式展开得到:w1×x1+w2×x2+w3×x3+w0。所以这两个单层感知器的表达不一样,但是计算结果是一样的。如图3.4的表达形式更加简洁,更适合使用矩阵来进行运算。
3.2.4单层感知器的学习规则
在3.2.3中我们已知单层感知器表达式可以写成:
(3.1)中y表示感知器的输出
f是sign激活函数
n是输入信号的个数
i=0,1,2…
(3.2)中ΔWi表示第i个权值的变化,η表示学习率(Learning rate),用来调节权值变化的大小
t是正确的标签(target)
因为单层感知器的激活函数为sign函数,所以t和y的取值都为±1
t=y时,ΔWi为0;t=1,y=-1时,ΔWi为2;t=-1,y=1时,ΔWi为-2。由(3.2)可以推出:
权值的调整公式为:
3.2.5单层感知器的学习规则计算举例
假设有一个单层感知器如图3.1所示,已知有三个输入x0=1,x1=0,x2=-1,权值w0=-5,w1=0,w2=0,学习率η=1,正确的标签t=1。(注意在这个例子中偏置值b用w0×x0来表示,x0的值固定为1)
Step1:我们首先计算感知器的输出:
由于y=-1与正确的标签t=1不相同,所以需要对感知器中的权值进行调节。
Step2:重新计算感知器的输出:
由于y=-1与正确的标签t=1不相同,所以需要对感知器中的权值进行调节。
Step3:重新计算感知器的输出:
由于y=1与正确的标签t=1相同,说明感知器经过训练后得到了我们想要的结果,我们就可以结束训练了。
把上面的例子写成python程序的话,可以得到代码3-1。
代码3-1:单层感知器学习规则计算举例
# 导入numpy 科学计算包
import numpy as np
# 定义输入
x0 = 1
x1 = 0
x2 = -1
# 定义权值
w0 = -5
w1 = 0
w2 = 0
# 定义正确的标签
t = 1
# 定义学习率lr(learning rate)
lr = 1
# 定义偏置值
b =0
# 循环一个比较大的次数,比如100
for i in range (100):
# 打印权值
print(w0,w1,w2)
# 计算感知器的输出
y = np.sign(w0 x0 +w1 x1+ w2 x2)
# 如果感知器输出不等于正确的标签
if(y != t):
# 更新权值
w0 = w0 + lr ( t - y ) x0
w1 = w1 + lr ( t -y) x1
w2 = w2 +lr ( t-y) x2
# 如果感知器输出等于正确的标签
else:
# 训练结束
print('done')
# 退出循环
break
程序的输出结果为:
-5 0 0
-3 0 -2
-1 0 -4
done
下面我们还可以用矩阵运算的方式来完成同样的计算
代码3-2:单层感知器学习规则计算举例(矩阵计算)
导入numpy 科学计算包
import numpy as np
# 定义输入,用大写字母表示矩阵
# 一般我们习惯用一行来表示一个数据,如果存在多个数据就用多行来表示
X = np.array([[1,0,-1]])
# 定义权值,用大写字母表示矩阵
# 神经网络中权值的定义可以参考神经网络的输入是输出神经元的个数
# 在本例子中输入神经元个数为3个,输出神经元个数为1个,所以可以定义3行1列的W
W = np.array([[-5],[0],[0]])
# 定义正确的标签
t = 1
# 定义学习率lr(learning rate)
lr = 1
# 定义偏置值
b = 0
# 循环一个比较大的次数,比如100
for i in range(100):
# 打印权值
print(W)
# 计算感知器的输出,np.dot可以看做是矩阵乘法
y = np.sign(np.dot(X,W))
# 如果感知器输出不等于正确的标签
if(y != t):
# 更新权值
# X.T表示X矩阵的转置
# 这里一个步骤可以完成代码3-1中下面3行代码完成的事情
# w0 = w0 + lr (t-y) x0
# w1 = w1 + lr (t-y) x1
# w2 = w2 + lr (t-y) x2
W =W +lr (t - y)X.T
# 如果感知器输出等于正确的标签
else:
# 训练结束
print('done')
# 退出循环
break
程序的输出结果为:
[[-5]
[ 0]
[ 0]]
[[-3]
[ 0]
[-2]]
[[-1]
[ 0]
[-4]]
done