Matlab神经网络学习笔记(一)
笔记目录
单层感知器介绍
单层感知器属于单层前向网络,即除了输入层和输出层以外,只有一层神经元节点。前向网络的特点是,输入数据从输入层经过隐藏层向输出层逐层传播,相邻两层的神经元相互连接,同一层的神经元之间则没有连接。
一、单纯感知器的结构
单层感知器是感知器中最简单的一种,由单个神经元组成的单层感知器只能用来解决线性可分的二类问题。(如果两类模式线性可分时,则算法一定收敛)
单层感知器是由一个线性组合器和一个两阈值原件组成。输入向量的各个向量与权值相乘,然后在线性组合器进行叠加,得到的结果是一个标量。线性组合器的输出是一个二值阈值原件的输入,得到线性组合结果经过一个二值阈值元件由隐含层传送到输出层,实际上这一步执行了一个符号函数。二值阈值元件通常是一个上升的函数,典型功能是将非负的输入值映射为1,负的输入值映射为-1或0。
考虑一个两类模式分类问题:输入是一个N维向量x=[x1,x2,···,xN],其中的每一个分量都对应一个权值是ωi,隐含层的数车叠加为一个标量值:
ν = ∑ i = 1 N x i ω i \nu= \sum_{i=1}^N {x_i}{\omega_i} ν=i=1∑Nxiωi
随后在二值阈值元件中对得到的v值进行判断,产生二值输出:
y = { 1 , ν >=0 0 , ν <0 y= \begin{cases} 1, & \text { $\nu$>=0} \\ 0, & \text{$\nu$<0} \end{cases} y={1,0, ν>=0ν<0
单层感知器可以输入数据分为两类:L1或L2。当y=1时,认为输入x=[x1,x2,···,xN]属于L1类,当y=-1时,认为输入认为输入x=[x1,x2,···,xN]属于L2类。但在实际应用中,除了输入的N维向量外,还有一个外偏置,值恒为1,权值为b。这样,输出y就可表示为
y = s g n ( ∑ i = 1 N ω i x i + b ) y=sgn\left( \sum_{i=1}^N {\omega_i }{x_i}+b \right) y=sgn(i=1∑Nωixi+b)
当维数N=2时,输入向量可表示为平面直角坐标系中的一个点。此时分类超平面是一条直线:
ω 1 x 1 + ω 2 x 2 + b = 0 \omega_1x_1+\omega_2x_2+b=0 ω1x1+ω2x2+b=0
结构图如图:
二、单层感知器的学习算法
在实际的应用中,需要使用计算机自动根据训练数据学习获得正确的权值,通常采用纠错学习规则的学习算法。
方便起见,修改单层感知器的结构如图所示,将偏置作为一个固定的输入。
因此,定义(N+1)* 1的输入向量:
x ( n ) = [ + 1 , x 1 ( n ) , x 2 ( n ) , ⋅ ⋅ ⋅ , x N ( n ) ] T x(n)=\left[+1,x_1(n),x_2(n),···,x_N(n)\right]^T x(n)=[+1,x1(n),x2(n),⋅⋅⋅,xN(n)]T
这里的n表示迭代次数。相应地,定义(N+1)* 1权值向量:
x ( n ) = [ b ( n ) , ω 1 ( n ) , ω 2 ( n ) , ⋅ ⋅ ⋅ , ω N ( n ) ] T x(n)=\left[b(n),\omega_1(n),\omega_2(n),···,\omega_N(n)\right]^T x(n)=[b(n),ω1(n),ω2(n),⋅⋅⋅,ωN(n)]T
因此线性组合器的输出为:
ν = ∑ i = 1 N x i ω i = ω T ( n ) x ( n ) \nu= \sum_{i=1}^N {x_i}{\omega_i}=\omega^T(n)x(n) ν=i=1∑Nxiωi=ωT(n)x(n)
令上式等于零,即可得到二分类问题的决策面。
学习算法步骤如下:
(1)定义变量和参数。
x(n)=N+1维输入向量
[ + 1 , x 1 ( n ) , x 2 ( n ) , ⋅ ⋅ ⋅ , x N ( n ) ] T \left[+1,x_1(n),x_2(n),···,x_N(n)\right]^T [+1,x1(n),x2(n),⋅⋅⋅,xN(n)]T
ω(n)=N+1维权值向量
[ b ( n ) , ω 1 ( n ) , ω 2 ( n ) , ⋅ ⋅ ⋅ , ω N ( n ) ] T \left[b(n),\omega_1(n),\omega_2(n),···,\omega_N(n)\right]^T [b(n),ω1(n),ω2(n),⋅⋅⋅,ωN(n)]T
b(n)=偏置
y(n)=实际输出
d(n)=期望输出
ŋ=学习效率参数,是一个比1小的正常数
(2)初始化。n=0,将权值向量ω设置为随机值或者全零值。
(3)激活。输入训练样本,对每个训练样本x(n)=[+1,x1(n),x2(n),···,xN(n)]’,指定其期望输出d,即若x∈l1,d=1,若x∈l2,d=-1。
(4)计算实际输出。
y = s g n ( ∑ i = 1 N ω T ( n ) x ( n ) ) y=sgn\left( \sum_{i=1}^N {\omega^T(n)}{x(n)} \right) y=sgn(i=1∑NωT(n)x(n))
sgn是符号函数
sgn 函数 返回一个 Variant (Integer),指出参数的正负号。 语法 sgn(number) 必要的 number 参数是任何有效的数值表达式。
即 x>0,sgnx= 1
x=0,sgnx= 0
x<0,sgnx=-1
(5)更新权值向量。
ω ( n + 1 ) = ω ( n ) + η [ d ( n ) − y ( n ) ] x ( n ) \omega(n+1)=\omega(n)+\eta \left[d(n)-y(n)\right]x(n) ω(n+1)=ω(n)+η[d(n)−y(n)]x(n)
这里
d ( n ) = { + 1 , x ( n ) ∈ l 1 − 1 , x ( n ) ∈ l 2 d(n)= \begin{cases} +1, & \text { $x(n)∈l_1$} \\ -1, & \text{$x(n)∈l_2$} \end{cases} d(n)={+1,−1, x(n)∈l1x(n)∈l2
0<ŋ<1
(6)判断。若满足收敛条件,则算法结束;若不满足,则n自增1(n=n+1),转到第三步继续执行
在计算时,收敛条件通常可以是:
(1)误差小于某个预先设定的较小的值ε。即
∣ d ( n ) − y ( n ) ∣ < ϵ |d(n)-y(n)|<\epsilon ∣d(n)−y(n)∣<ϵ
(2)两次迭代之间的权值变化已经很小,即
∣ ω ( n + 1 ) − ω ( n ) ∣ < ϵ |\omega(n+1)-\omega(n)|<\epsilon ∣ω(n+1)−ω(n)∣<ϵ
(3)设定最大迭代数M,当迭代M次之后算法就停止迭代。
学习效率ŋ的值决定了误差对权值的影响大小,ŋ的值既不能过大也不能太小。
单层感知器只对线性可分的问题收敛,通过学习调整权值,最终找到合适的决策面,实现正确分类。
三、感知器的局限性
(1)感知器的激活函数使用阈值函数,使得输出只能取两个值(-1/1或0/1),因此限制在分类种类上的扩展。
(2)只对线性可分的问题收敛。
(3)如果输入样本存在奇异样本,则网络需要花费很长时间。(奇异样本是数值上远远偏离其他样本的数据)。
(4)感知器的学习算法只对单层有效,因此无法套用其规则设计多层感知器。
四、单层感知器相关函数详解
最主要的三个函数newp、train和sim
分别用来设计、训练和仿真。
newp—创建一个感知器
net=newp(P,T,TF,LF)
P:是一个R*2矩阵,矩阵行数R等于感知器网络中输入向量的维数。矩阵每一行表示输入向量每个分量的取值范围,如P=[-1,0;0,1],就表示输入向量是[x1,x2],即-1<x1<0,0<x2<1
P = [ − 1 0 0 1 ] P=\begin{bmatrix} -1 & 0\\ 0 & 1 \\ \end{bmatrix} P=[−1001]
因此,第一列数字一定要小于第二列数字
T:表示输出节点的个数,标量
TF:传输函数。可取值为hardlim或hardlims,默认为hardlim。(后面会说到hadlim与hadlims的区别)
LF:学习函数,可取值为learnp或learnpn,默认值learnp (输入向量数值幅度变化较大时,采用learnpn代替learnp,可以加快计算速度。)
net:返回的感知器网络。
train—训练感知器网络
[net,tr]=train(net,P,T,Pi,Ai)
net:需要训练的神经网络
P:网络输入。P是R*Q输入矩阵,每一列是一个输入向量,R应等于网络的输入节点个数,共有Q个训练输入向量。
T:网络期望输出。默认值为0。
(注意:P与T的列数应该相等)
Pi:初始输入延迟,默认0
Ai:初始的层延迟,默认0
net:训练好的网络
tr:训练记录,包括训练步数epoch和性能perf。
对于没有输入延迟或者层延迟的网路。Pi,Ai,Pf和Af是不需要的。
sim—对训练好的网络进行仿真
[Y,Pf,Af]=sim(net,P,Pi,Ai)
P:网络输入同上。
Pi初始输出延迟
Ai初始层延迟
Y:网络对输入P的实际输出
Pf:最终输出延迟
Af:最终的层延迟
(sim和train函数相似,对没有延迟的网络Pi,Ai,Pf,Af都是不必要的)
实例1 用newp函数创建一个感知器,并进行训练仿真。
p=[-1,1;-1,1] %输入两个分量,两个分量的取值范围均为-1~1
t=1 %共有一个输出节点
net=newp(p,t) %创建感知器
P=[0,0,1,1;0,1,0,1] %用于训练的输入数据,每列是一个输入向量
%个人理解:输入向量P实际上就是(0,0),(0,1),(1,0),(1,1)这四个点
T=[0,1,1,1] %输入数据的期望输出
net=train(net,P,T) %train函数用于训练
newP1=[0;0.7] %测试数据1 表示点(0,0.7)
newT1=sim(net,newP1)
结果>>0
newP2=[0.7;0.7] %测试数据1 表示点(0.7,0.7)
newT2=sim(net,newP2)
结果>>1
newT=sim(net,P) %原数据测试,实际输出等于期望输出
结果>>0 1 1 1
实例2 创建一个感知器,用来判断输入数字的符号,非负数输出为1,负数输出为0,用train进行训练。
p=[-100,100];
t=1;
net=newp(p,t);
P=[-5,-4,-3,-2,-1,0,,1,2,3,4,5];
T=[0,0,0,0,0,1,1,1,1,1,1];
net=train(net,P,T);
newP=-10:0.2:10;
newT=sim(net,nweP);
plot(newP,newT,'r-');
title('判断正负单层感知器');
hardlim/hardlims—感知器传输函数
hardlim和hardlims都是感知器传输函数,其功能类似数学上的符号函数。
s g n ( x ) = { 1 , x > 0 0 , x = 0 − 1 , x < 0 sgn(x)=\begin{cases} 1, & \text {$x>0$ } \\ 0, & \text{ $x=0$ }\\ -1, & \text { $x<0$ } \end{cases} sgn(x)=⎩⎪⎨⎪⎧1,0,−1,x>0 x=0 x<0
hardlim将-1用0替换
y = { 1 , x >0 0 , x <=0 y= \begin{cases} 1, & \text { $x$>0} \\ 0, & \text{$x$<=0} \end{cases} y={1,0, x>0x<=0
A=hardlim(N,FP)或A=hardlims(N,FP)
N:为输入向量
FP:则是可选参数
init—神经网络初始化函数
net=init(net)
init(net)的功能是初始化神经网络net的权值和阈值。init内部使用的初始化函数是由net.initFcn指定的,其参数是由net.initParam确定的。
通过调用特定的初始化函数初始化权值和阈值,通常为rands函数,它可以产生-1~1的随机数
实例
net=nwep([0,1;-2,2],1); %创建感知器
net.iw{1,1} %创建时的权值
结果>>0 0
net.b{1} %创建时的偏置
结果>>0
P=[0,1,0,1;0,0,1,1] %训练输入的向量
T=[0,0,0,1] %期望输出
net=train(net,P,T); %训练
net.iw{1,1} %训练后的权值
结果>>1 2
net.b{1} %训练后的偏置
结果>>0
net=init(net); %初始化
net.iw{1,1} %初始化后的权值
结果>>0 0
net.b{1} %初始化后的偏置
结果>>0
adapt—神经网络的自适应
[net,Y,E,Pf,Af,tr]=adapt(net,P,T,Pi,Ai)
功能:调整神经网络误差
adapt在线性网络中比较常用
mae—平均绝对误差性函数
pref=mae(E)
mae是一个网路性能函数,用平均值绝对误差来衡量性能。其他性能还有mse(平方误差),sse(误差平方和)等
实例1 创建一个感知器,计算仿真时的误差性能
net=nwep([-10,10],1);
P=[-10,-5,0,5,-10];
T=[0,0,1,1,1];
Y=sim(net,P)
>>1 1 1 1 1
e=T-Y
>>-1 -1 0 0 0
pref=mae(e) %sum(abs(e))/length(e)
>>0.4000
net=train(net,P,T);
Y=sim(net,P);
e=T-Y;
>>0 0 0 0 0
perf=mae(e)
>>0
在实际运算中,当mae=0时算法收敛,即使继续更新权值,其值也不会发生变化