单层感知器应用实例——坐标点的分类问题
单层感知器应用实例——坐标点的分类问题
问题描述:给定二维平面的六个点,利用单层感知器进行分类
一、手算
给定六个点,如下图1-1所示:
序号 | X | Y | 所属类型 |
---|---|---|---|
1 | -9 | 15 | 0 |
2 | 1 | 8 | 1 |
3 | -12 | 4 | 0 |
4 | -4 | 5 | 0 |
5 | 0 | 11 | 0 |
6 | 5 | 9 | 1 |
这是一个线性可分问题,输入的是2维向量,在2微空间中可用一条直线将两个大类正确地分开,需要达到打效果如下图:
由于输入的向量维数为2,输出的向量维数为1,因此,创建感知器网络只有一个输出节点,有两个输入节点,网络的结构图如下:
网络中需要求解的权值是\(\omega_1\)和\(\omega_2\)以及偏置b.
手算的步骤如下
-
定义向量
\[\omega=[b,\omega_1,\omega_2]^T \]定义输入输入向量
\[P=\left[\begin{matrix} 1,x_1,y_1\\ 1,x_2,y_2\\ ... \end{matrix}\right]^T \]期望输出:
\[d=[0,1,0,0,1]^T \] -
在MATLAB中逐步实现:
定义好学习率、输出向量、初始化权值和偏置($$\omega=[b,\omega_1,\omega_2]T=[0,0,0]T$$)
n=0.2; % 学习率 w=[0,0,0]; P=[ -9, 1, -12, -4, 0, 5; 15, -8, 4, 5, 11, 9]; d=[0,1,0,0,0,1]; % 期望输出 P=[ones(1,6);P];
-
第一次迭代根据\(v=\omega P\)和\(y=hardlim(v)\)(传输函数)计算输出,输出值为0或1.
>> v=w*P; v = 0 0 0 0 0 0 >> y=hardlim(v); y = 1 1 1 1 1 1
\(y\)是实际输出,与期望值\(d=[0,1,0,0,0,1]\)出入,根据误差\((d-y)\)来调整权值和偏置,公式:
\[\omega=\omega+(d-y)P^T \]>> e=(d-y) e = -1 0 -1 -1 -1 0 >> ee=mae(e) ee = 0.6667 >> w=w+n*(d-y)*P' w = -0.8000 5.0000 -7.0000
-
第一次迭代误差的平均绝对误差是0.6667,第二次迭代在第一次迭代的基础上重新开始计算:
>> v=w*P v = -150.8000 60.2000 -88.8000 -55.8000 -77.8000 -38.8000 >> y=hardlim(v) % 实际输出 y = 0 1 0 0 0 0 >> e=(d-y) %误差 e = 0 0 0 0 0 1 >> ee=mae(e)%计算误差的平均绝对差 ee = 0.1667 >> w=w+n*(d-y)*P'%再次调整 w = -0.6000 6.0000 -5.2000
-
第三次和第四次迭代,重复上面步骤,第四次迭代结束后结果如下:
>> v=w*P v = -114.4000 33.8000 -98.0000 -45.4000 -37.8000 4.0000 >> y=hardlim(v) y = 0 1 0 0 0 1 >> e=(d-y) e = 0 0 0 0 0 0 >> ee=mae(e) ee = 0 >> w=w+n*(d-y)*P' w = -0.4000 7.0000 -3.4000
第四次迭代后mae的值已经为零,得到最终的权值和偏置,\(\omega=[-0.4,7,-3.4]^T\).得到的直线是\(7x-3.4y-0.4=0\),如图:
用循环实现:
%% 清理
clear,clc
close all
%%
n=0.2; % 学习率
w=[0,0,0];
P=[ -9, 1, -12, -4, 0, 5;
15, -8, 4, 5, 11, 9];
d=[0,1,0,0,0,1]; % 期望输出
P=[ones(1,6);P];
MAX=20; % 最大迭代次数为20次
%% 训练
i=0;
while 1
v=w*P;
y=hardlim(v) % 实际输出
%更新
e=(d-y) %误差
ee(i+1)=mae(e);
if (ee(i+1)<0.001) % 判断
disp('we have got it:');
disp(w);
break;
end
% 更新权值和偏置
w=w+n*(d-y)*P';
if (i>=MAX) % 达到最大迭代次数,退出
disp('MAX times loop');
disp(w);
disp(ee(i+1));
break;
end
i= i+1;
end
%% 显示
figure;
subplot(2,1,1); % 显示待分类的点和分类结果
plot([-9 , -12 -4 0],[15, 4 5 11],'o');
hold on;
plot([1,5],[-8,9],'*');
axis([-13,6,-10,16]);
legend('第一类','第二类');
title('6个坐标点的二分类');
x=-13:.2:6;
y=x*(-w(2)/w(3))-w(1)/w(3);
plot(x,y);
hold off;
subplot(2,1,2); % 显示mae值的变化
x=0:i;
plot(x,ee,'o-');
s=sprintf('mae的值(迭代次数:%d)', i+1);
title(s);
使用神经网络工具箱:
%% 使用神经网络工具箱
%% 清理
clear,clc
close all
%% 创建感知器
p=[-20,-20;-20,-20]
t=1
net=newp(p,t)
%定义输入向量
P=[ -9, 1, -12, -4, 0, 5;
15, -8, 4, 5, 11, 9];
%期望输出
T=[0 1 0 0 0 1]
%开始训练
net=train(net,P,T)
%仿真
y=sim(net,P)
%权值和偏置
iw=net.IW
iw[1]
b=net.b
w=[b{1},iw{1}]
%% 显示
figure;
plot([-9 , -12 -4 0],[15, 4 5 11],'o');
hold on;
plot([1,5],[-8,9],'*');
axis([-13,6,-10,16]);
legend('第一类','第二类');
title('6个坐标点的二分类');
x=-13:.2:6;
y=(7/3)*x;
plot(x,y);
神经网络工具箱计算出来的结果中偏置为0,权值分别为14,-6;