感知机和BP神经网络

一、感知机

1.感知机的概念

感知机是用于二分类的线性分类模型,其输入是实例的特征向量,输出是实例的类别,类别取+1和-1二个值,+1代表正类,-1代表负类。感知机对应于输入空间(特征空间)中将实例分为正负两类的分割超平面,属于判别模型。感知机学习算法简单易于实现,分为原始形式和对偶形式。

2.感知机的原理

感知机是二分类的线性模型,其输入是实例的特征向量,输出的是事例的类别,分别是+1和-1,属于判别模型。

假设训练数据集是线性可分的,感知机学习的目标是求得一个能够将训练数据集正实例点和负实例点完全正确分开的分离超平面。如果是非线性可分的数据,则最后无法获得超平面

 

3.感知机的损失函数

我们首先定义对于样本(xi,yi)(xi,yi),如果wxi+b||w||>0w⋅xi+b||w||>0则记yi=+1yi=+1,如果wxi+b||w||<0w⋅xi+b||w||<0则记yi=1yi=−1。

这样取y的值有一个好处,就是方便定义损失函数。因为正确分类的样本满足yi(wxi+b)||w||>0yi(w⋅xi+b)||w||>0,而错误分类的样本满足yi(wxi+b)||w||<0yi(w⋅xi+b)||w||<0。我们损失函数的优化目标,就是期望使误分类的所有样本,到超平面的距离之和最小

所以损失函数定义如下:

L(w,b)=1||w||xiMyi(wxi+b)L(w,b)=−1||w||∑xi∈Myi(w⋅xi+b)


其中M集合是误分类点的集合。

 

不考虑1||w||1||w||,就得到感知机模型的损失函数:

L(w,b)=xiMyi(wxi+b)

二、BP神经网络

 1.BP神经网络流程

神经网络的基本组成单元是神经元。神经元的通用模型如图所示,其中常用的激活函数有阈值函数、sigmoid函数和双曲正切函数。 

 
神经元模型

神经元的输出为: 

 
神经元输出

神经网络是将多个神经元按一定规则联结在一起而形成的网络,如图 所示。 

 
神经网络示意图 

从图 可以看出,一个神经网络包括输入层、隐含层(中间层)和输出层。输入层神经元个数与输入数据的维数相同,输出层神经元个数与需要拟合的数据个数相同,隐含层神经元个数与层数就需要设计者自己根据一些规则和目标来设定。在深度学习出现之前,隐含层的层数通常为一层,即通常使用的神经网络是3层网络。 

2.神经网络的公式

2.1.输出层到隐藏层:

αh=∑i=1dvih∗xi⋯⋯⋯⋯⋯⋯⋯(1)
αh=∑i=1dvih∗xi⋯⋯⋯⋯⋯⋯⋯(1)

|x1x2x3⋯xd|⋅∣∣∣∣∣∣∣∣∣v11v21⋅⋅⋅vd1v12v22⋅⋅⋅wd2v13v23⋅⋅⋅wd3⋯⋯⋅⋅⋅⋯v1qw2q⋅⋅⋅wdq∣∣∣∣∣∣∣∣∣
|x1x2x3⋯xd|⋅|v11v12v13⋯v1qv21v22v23⋯w2q⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅vd1wd2wd3⋯wdq|
  2.2.经过隐藏层的激活函数:
bh=f(αh−γh)⋯⋯⋯⋯⋯⋯⋯(2)
bh=f(αh−γh)⋯⋯⋯⋯⋯⋯⋯(2)
  2.3.隐藏层到输出层:
βj=∑h=1qwhj∗bh⋯⋯⋯⋯⋯⋯⋯(3)
βj=∑h=1qwhj∗bh⋯⋯⋯⋯⋯⋯⋯(3)
  用矩阵表示
|b1b2b3⋯bq|⋅∣∣∣∣∣∣∣∣∣w11w21⋅⋅⋅wq1w12w22⋅⋅⋅wq2w13w23⋅⋅⋅wq3⋯⋯⋅⋅⋅⋯w1lw2l⋅⋅⋅wql∣∣∣∣∣∣∣∣∣
|b1b2b3⋯bq|⋅|w11w12w13⋯w1lw21w22w23⋯w2l⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅wq1wq2wq3⋯wql|
  2.4.经过输出层的激活函数:
yk,j=f(βj−θj)⋯⋯⋯⋯⋯⋯⋯(4))
yjk,=f(βj−θj)⋯⋯⋯⋯⋯⋯⋯(4))
  2.5.误差:
Ek=12∑j=1l(yk,j−ykj)2⋯⋯⋯⋯⋯⋯⋯(5)
Ek=12∑j=1l(yjk,−yjk)2⋯⋯⋯⋯⋯⋯⋯(5)

  综上我们可以得知whjwhj先影响βjβj,再影响yk,jyjk,,最后影响EkEk,(一个ww权值只会影响一个ββ)所以我们可得:
Δwhj=−η∂Ek∂whj=−η∂Ek∂yk,j⋅∂yk,j∂βj⋅∂βj∂whj⋯(6)
Δwhj=−η∂Ek∂whj=−η∂Ek∂yjk,⋅∂yjk,∂βj⋅∂βj∂whj⋯(6)

其中∂βj∂whj=bh∂βj∂whj=bh,前面提到过,bhbh是第h个隐藏神经元的输出。
gj=∂Ek∂yk,j⋅∂yk,j∂βj=(yk,j−ykj)⋅f′(βj−θj)⋯(7)
gj=∂Ek∂yjk,⋅∂yjk,∂βj=(yjk,−yjk)⋅f′(βj−θj)⋯(7)

  而我们选择的激活函数是SigmodSigmod函数,该函数具有一个很好的性质
f(x)=11+e−x⋯f′(x)=f(x)(1−f(x))⋯(8)
f(x)=11+e−x⋯f′(x)=f(x)(1−f(x))⋯(8)

  所以我们有:
f′(βj−θj)=f(βj−θj)⋅(1−f(βj−θj))=yk′j⋅(1−yk′j)⋯(9)
f′(βj−θj)=f(βj−θj)⋅(1−f(βj−θj))=yjk′⋅(1−yjk′)⋯(9)

  综合formula(6)(7)(9)formula(6)(7)(9)我们可得:
Δwhj=−η∂Ek∂whj=−ηgibh=−η(yk′j−ykj)⋅yk′j⋅(1−yk′j)⋅bh⋯(10)
Δwhj=−η∂Ek∂whj=−ηgibh=−η(yjk′−yjk)⋅yjk′⋅(1−yjk′)⋅bh⋯(10)
  同理:
Δθj=−η∂Ek∂θj=−η∂Ek∂yk′j⋅∂yk′j∂θj=η⋅gj⋯(11)
Δθj=−η∂Ek∂θj=−η∂Ek∂yjk′⋅∂yjk′∂θj=η⋅gj⋯(11)

  我们再看看ΔvihΔvih的值怎么求,还是由formula(1),(2),(3),(4),(5)formula(1),(2),(3),(4),(5)推导,一个vv权值会影响所有的ββ
Δvih=−ηehxi⋯⋯⋯⋯(12)
Δvih=−ηehxi⋯⋯⋯⋯(12)

Δγh=ηeh⋯⋯ ⋯(13)
Δγh=ηeh⋯⋯ ⋯(13)

  其中
eh=(∑j=1l∂Ek∂βj⋅∂βj∂bj)⋅f′(αh−γh)=(∑j=1l(yk,j−ykj)⋅f′(βj−θj)⋅whj)⋅f′(αh−γh)⋯⋯⋯(14)
三、感知器神经网络的构建

% 1.1 生成网络
net=newp([0 2],1);%单输入,输入值为[0,2]之间的数
inputweights=net.inputweights{1,1};%第一层的权重为1
biases=net.biases{1};%阈值为1
% 1.2 网络仿真

net=newp([-2 2;-2 2],1);%两个输入,一个神经元,默认二值激活
net.IW{1,1}=[-1 1];%权重,net.IW{i,j}表示第i层网络第j个神经元的权重向量
net.IW{1,1}
net.b{1}=1;
net.b{1}
p1=[1;1],a1=sim(net,p1)
p2=[1;-1],a2=sim(net,p2)
p3={[1;1] [1 ;-1]},a3=sim(net,p3) %两组数据放一起
p4=[1 1;1 -1],a4=sim(net,p4)%也可以放在矩阵里面
net.IW{1,1}=[3,4];
net.b{1}=[1];
a1=sim(net,p1)
% 1.3 网络初始化
net=init(net);
wts=net.IW{1,1}
bias=net.b{1}
% 改变权值和阈值为随机数
net.inputweights{1,1}.initFcn='rands';
net.biases{1}.initFcn='rands';
net=init(net);
bias=net.b{1}
wts=net.IW{1,1}
a1=sim(net,p1)

% 2. 感知器神经网络的学习和训练
% 1 网络学习
net=newp([-2 2;-2 2],1);
net.b{1}=[0];
w=[1 -0.8]
net.IW{1,1}=w;
p=[1;2];
t=[1];
a=sim(net,p)
e=t-a
help learnp
dw=learnp(w,p,[],[],[],[],e,[],[],[],[],[])
w=w+dw
net.IW{1,1}=w;
a=sim(net,p)


net = newp([0 1; -2 2],1);
P = [0 0 1 1; 0 1 0 1];
T = [0 1 1 1];
Y = sim(net,P)
net.trainParam.epochs = 20;
net = train(net,P,T);
Y = sim(net,P)


% 2 网络训练
net=init(net);
p1=[2;2];t1=0;p2=[1;-2];t2=1;p3=[-2;2];t3=0;p4=[-1;1];t4=1;
net.trainParam.epochs=1;
net=train(net,p1,t1)
w=net.IW{1,1}
b=net.b{1}
a=sim(net,p1)
net=init(net);
p=[[2;2] [1;-2] [-2;2] [-1;1]];
t=[0 1 0 1];
net.trainParam.epochs=1;
net=train(net,p,t);
a=sim(net,p)
net=init(net);
net.trainParam.epochs=2;
net=train(net,p,t);
a=sim(net,p)
net=init(net);
net.trainParam.epochs=20;
net=train(net,p,t);
a=sim(net,p)

% 3. 二输入感知器分类可视化问题
P=[-0.5 1 0.5 -0.1;-0.5 1 -0.5 1];
T=[1 1 0 1]
net=newp([-1 1;-1 1],1);
plotpv(P,T);
plotpc(net.IW{1,1},net.b{1});
%hold on;
%plotpv(P,T);
net=adapt(net,P,T);
net.IW{1,1}
net.b{1}
plotpv(P,T);
plotpc(net.IW{1,1},net.b{1})
net.adaptParam.passes=3;
net=adapt(net,P,T);
net.IW{1,1}
net.b{1}
plotpc(net.IW{1},net.b{1})
net.adaptParam.passes=6;
net=adapt(net,P,T)
net.IW{1,1}
net.b{1}
plotpv(P,T);
plotpc(net.IW{1},net.b{1})

plotpc(net.IW{1},net.b{1})
%仿真
a=sim(net,p);
plotpv(p,a)

p=[0.7;1.2]
a=sim(net,p);
plotpv(p,a);
hold on;
plotpv(P,T);
plotpc(net.IW{1},net.b{1})
%感知器能够正确分类,从而网络可行。

% 4. 标准化学习规则训练奇异样本
P=[-0.5 -0.5 0.3 -0.1 -40;-0.5 0.5 -0.5 1.0 50]
T=[1 1 0 0 1];
net=newp([-40 1;-1 50],1);
plotpv(P,T);%标出所有点
hold on;
linehandle=plotpc(net.IW{1},net.b{1});%画出分类线
E=1;
net.adaptParam.passes=3;%passes决定在训练过程中训练值重复的次数。
while (sse(E))
[net,Y,E]=adapt(net,P,T);
linehandle=plotpc(net.IW{1},net.b{1},linehandle);
drawnow;
end;
axis([-2 2 -2 2]);
net.IW{1}
net.b{1}
%另外一种网络修正学习(非标准化学习规则learnp)
hold off;
net=init(net);
net.adaptParam.passes=3;
net=adapt(net,P,T);
plotpc(net.IW{1},net.b{1});
axis([-2 2 -2 2]);
net.IW{1}
net.b{1}
%无法正确分类
%标准化学习规则网络训练速度要快!

% 训练奇异样本
% 用标准化感知器学习规则(标准化学习数learnpn)进行分类
net=newp([-40 1;-1 50],1,'hardlim','learnpn');
plotpv(P,T);
linehandle=plotpc(net.IW{1},net.b{1});
e=1;
net.adaptParam.passes=3;
net=init(net);
linehandle=plotpc(net.IW{1},net.b{1});
while (sse(e))
[net,Y,e]=adapt(net,P,T);
linehandle=plotpc(net.IW{1},net.b{1},linehandle);
end;
axis([-2 2 -2 2]);
net.IW{1}%权重
net.b{1}%阈值
%正确分类

%非标准化感知器学习规则训练奇异样本的结果
net=newp([-40 1;-1 50],1);
net.trainParam.epochs=30;
net=train(net,P,T);
pause;
linehandle=plotpc(net.IW{1},net.b{1});
hold on;
plotpv(P,T);
linehandle=plotpc(net.IW{1},net.b{1});
axis([-2 2 -2 2]);

% 5. 设计多个感知器神经元解决分类问题
p=[1.0 1.2 2.0 -0.8; 2.0 0.9 -0.5 0.7]
t=[1 1 0 1;0 1 1 0]
plotpv(p,t);
hold on;
net=newp([-0.8 1.2; -0.5 2.0],2);
linehandle=plotpc(net.IW{1},net.b{1});
net=newp([-0.8 1.2; -0.5 2.0],2);
linehandle=plotpc(net.IW{1},net.b{1});
e=1;
net=init(net);
while (sse(e))
[net,y,e]=adapt(net,p,t);
linehandle=plotpc(net.IW{1},net.b{1},linehandle);
drawnow;
end;

posted @ 2019-09-30 21:44  MangoWu  阅读(984)  评论(0编辑  收藏  举报