单层感知器应用实例——坐标点的分类问题

问题描述:给定二维平面的六个点,利用单层感知器进行分类


一、手算

给定六个点,如下图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.

手算的步骤如下

  1. 定义向量

    \[\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 \]

  2. 在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];
    
  3. 第一次迭代根据\(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
    
  4. 第一次迭代误差的平均绝对误差是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
    
  5. 第三次和第四次迭代,重复上面步骤,第四次迭代结束后结果如下:

    >> 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;