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

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


一、手算

给定六个点,如下图1-1所示:

单层感知器网络pytorch_单层感知器网络pytorch

序号

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微空间中可用一条直线将两个大类正确地分开,需要达到打效果如下图:

单层感知器网络pytorch_权值_02

由于输入的向量维数为2,输出的向量维数为1,因此,创建感知器网络只有一个输出节点,有两个输入节点,网络的结构图如下:

单层感知器网络pytorch_迭代_03

网络中需要求解的权值是\(\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];
  1. 第一次迭代根据\(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
  1. 第一次迭代误差的平均绝对误差是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
  1. 第三次和第四次迭代,重复上面步骤,第四次迭代结束后结果如下:
>> 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\),如图:

单层感知器网络pytorch_感知器_04

用循环实现:

%% 清理
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);

单层感知器网络pytorch_单层感知器网络pytorch_05

使用神经网络工具箱:

%% 使用神经网络工具箱
%% 清理
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);

单层感知器网络pytorch_单层感知器网络pytorch_06

神经网络工具箱计算出来的结果中偏置为0,权值分别为14,-6;