%给定样本输入向量P,目标输出向量T
%net = newp(PR,S,TF,LF)
%PR为输入矢量的取值范围的最大值和最小值 S为神经元的个数 TF为网络的传递函数 默认为hardlim LF为网络的学习函数 默认为learnp
%以及需要分类的向量组Q
%设计一个单层感知机对其分类
%[net,tr,Y,E,Pf,Af] = train(net,P,Pi,Ai)
%train通过调用网络训练函数net.trainFcn并根据训练函数net.trainParam对网络进行训练
%在输入变量中net为神经网络对象 P为网络输入 T为目标矢量Pi为输入延迟的初始状态 Ai为层延迟的初始状态
%在返回函数中net为新的网络 tr为训练记录 Y为网络输出 E为输出和目标矢量之间的误差 Pf为训练终止时输入的延时状态
%Af为训练终止时的层延时状态
P = [-0.3 -0.8 0.4;0.6 0 0.1];
T = [1 1 0];
net = newp([-1 1;-1 1],1); %设置单层感知器
net.trainParam.epochs = 10; %设置网络的最大训练次数为20
net = train(net,P,T); %使用训练函数对创建的网络进行训练
Y = sim(net,P); %对训练后的网络进行仿真
E1 = mae(Y-T); %计算输出量与目标量之间的均方误差
Q = [0.6 0.9 -0.1;-0.1 -0.5 0.5]; %检测训练好的神经网络的性能
Y1 = sim(net,Q); %对网络进行仿真,仿真输出即为分类的结果
figure; %创建一个绘图的窗口
plotpv(Q,Y1); %绘制输入向量和目标向量plotpv(P,T,V)输入向量、目标向量、控制图形的最大范围
plotpc(net.iw{1},net.b{1}); %在感知器向量图中绘制分界线plotpc(W,B,H)加权矩阵、阈值向量、最后画线的控制权
分类结果:
对于线性不可分的例子,如下图的两类模式(类a表示垂直线 类b表示平行线)通过感知器网络分类。显然对于两类模式类别无法用一个超平面分开,所以单层感知器是无法完成此任务。这里设置一个多层感知器网络来解决此问题。
多层感知器的结构如下,其中对应的传递函数f为强限幅传递函数:
对应强限幅传递函数公式如下:
通过依次扫描模式中的各列,将模式表示成向量。白方块用”-1“ 表示,黑方块用”1“表示,对于样本希望分两类即垂直的为1 水平的为0,则输入样本用p1 p2 p3 p4 表示,如下表:
输入样本 | 目标向量 | |
p1 | 1 1 -1 -1 | 1 |
p2 | -1 -1 1 1 | 1 |
p3 | 1 -1 1 -1 | 0 |
p4 | -1 1 -1 1 | 0 |
将输入向量的前两个输入输入第一层感知器的第一个神经元,将输入向量的后两个输入输入第一层感知器的第二个神经元,运算结果如下图所示,其中p1、p11分别为两个神经元的输入,b1、b11分别为两个神经元的偏置(随机得到),iw1、iw11分别为两个神经元的[1行2列]权值矩阵(随机的到)a1、a11分别为两个神经元的输出。
第一次输入具体计算公式如下:
将第一层神经元输出组合后组成[2*4]的矩阵输入第二层神经元,在第二层神经元训练仿真后若输入的向量满足目标向量则训练结束。训练完成后得到的net可对输入向量进行分类。
在命令行输入
sim(net2,p2)
得到结果:
满足最初目标垂直线样本标记为1 水平线标记为0 。
上述非线性可分样例的代码如下:
pr1 = [-1 1;-1 1];%随机感知器 输入的范围
net1 = newp(pr1,1);
net11 = newp(pr1,1);
%%
%随机权重、偏置参数
net1.inputweights{1}.initFcn = 'rands';
net1.biases{1}.initFcn = 'rands';
net11.inputweights{1}.initFcn = 'rands';
net11.biases{1}.initFcn = 'rands';
index = 0;
while index == 0
%%
%第一层
%神经元1
net1 = init(net1);
%iw1[1 2] * p1[2 4] = a1[1 4];
%表示输入层到第一层隐层的权重
iw1 = net1.IW{1};%net.IW{i,j}表示从第j个输出到第i层权重的权重矩阵,其值为N*R的矩阵
b1 = net1.b{1}; %表示第一层隐层的偏置,其值为N*1的矩阵
p1 = [1 -1 1 -1;1 -1 -1 1]; %第一层第一个单层感知器的输入
[a1] = sim(net1,p1); %进行仿真,输出结果到a1
%神经元2
%iw11[1 2] * p11[2 4] = a11[1 4];
net11 = init(net11);
iw11 = net11.IW{1};
b11 = net11.b{1};
p11 = [-1,1,1,-1;-1,1,-1,1];%第一层第二个单层感知器的输入
[a11] = sim(net11,p11); %进行仿真,输出结果到a11
%%
%第二层
pr2 = [0 1;0 1];
net2 = newp(pr2,1); %第二层单个感知器建立,一个神经元
net2.trainParam.epochs = 10;%最大训练次数(步数)设置为10
net2.trainParam.show = 1; %每隔一次展示一下训练结果
p21 = ones(size(a1));
p21 = p21.*a1;
p22 = ones(size(a11));
p22 = p22.*a11;
p2 = [p21;p22]; %第一层中两个单层感知器的输出作为第二层单层感知器的输入
t2 = [1 1 0 0]; %目标向量
[net2,tr2] = train(net2,p2,t2);%第二层单层感知器的训练
epoch2 = tr2.epoch;
perf2 = tr2.perf;
iw2 = net2.IW{1};
b2 = net2.b{1};
a2 = sim(net2,p2); %第二层进行仿真
save Percept02 net1 net2
if a2 == t2 %结束条件,当训练结果满足目标向量时结束训练
index = 1;
end
end