当前位置:   article > 正文

从0到专业:一步步从感知机到matlab中的《感知机神经网络》_matlab神经网络one-hot iris

matlab神经网络one-hot iris

原创文章,转载请说明来自《老饼讲解-BP神经网络》:www.bbbdata.com

关于《老饼讲解-BP神经网络》:

本网结构化讲解神经网络的知识,原理和代码。

重现matlab神经网络工具箱的算法,是学习神经网络的好助手。 


目录

一、初识感知机

01.感知机的思想  

02.简单Demo

二、感知机原理与自实现感知机

01.模型数学表达式  

​02.感知机的训练目标与损失函数

03.损失函数的梯度

04.算法流程  

05.实现代码  

三、matlab中的感知机神经网络 

01.感知机神经网络的拓扑结构   

02.感知机神经网络的数学表达式

03.辨识:与二分类感知机的区别  

04.训练目标与损失函数 

05.损失函数的梯度 

06.算法流程

07.代码实现-自己实现newp

四、matlab神经网络工具箱的感知机实现与说明

01. 简单Demo  

02. 工具箱说明  


感知机(perceptron)由Rosenblatt在1957提出,只解决二分类问题,
它的输出为-1或1,是神经网络与支持向量基的基础。
本文先讲述感知机的原理、算法流程及代码实现,

然后讲解matlab中单层感知机神经网络的原理和代码实现(非调包)。

最后讲解matlab如何通过工具箱使用感知机神经网络。


一、初识感知机

01.感知机的思想  


在输入为二维的时候,
单层感知机就相当于找出一条直线(在多维的时候,就是平面或超平面),
将平面一分为二,一边为正样本,另一边为负样本

02.简单Demo


通过matlab工具箱实现一个简单Demo  
  matlab工具箱使用感知机神经网络的Demo代码(2014b版matlab实测已跑通):
  

  1. % 训练数据
  2. X = [0 0 1 1; 0 1 0 1];
  3. y = [0 1 1 1;];
  4. %训练
  5. net = newp(X,y);             % 建立网络
  6. [net,tr]  = train(net,X,y);  % 训练网络
  7. %预测
  8. py = sim(net,X) %使用网络进行预测


二、感知机原理与自实现感知机

01.模型数学表达式  


感知机的模型数学表达式为:

\text{y} = \textbf{sign}(wx+b )

其中,

\textbf{sign}(x) = \left\{\begin{matrix} 1 & \text{ if x}\geqslant 0\\ -1 & \text{ if x}<0 \end{matrix}\right.



02.感知机的训练目标与损失函数


训练目标  

感知机的误差评估函数为误分类的占比

\displaystyle \textbf{E} = \dfrac{1}{n} \sum\limits _{i}^{n}\begin{cases} 0 & \text{ if } \text{p}_i= \text{y}_i\\ 1 & \text{ else } \end{cases}



其中,\text{p}_i= \textbf{sign}(wx_i+b ),即感知机对第i个样本的预测值。
感知机的训练目标就是找出一组w,b,使E最小化。

损失函数  

感知机的训练可以使用梯度下降法,
但由于误差评估函数,不方便求导,
所以先构造一个与误差评估函数相关的损失函数,
然后用损失函数的梯度来引导w,b的调整。


可以用以下函数作为损失函数,来引导w,b的迭代方向。

\displaystyle L(w,b) = -\sum \limits_{i} \text{y}_i(wx_i+b)

上式的意义如下:
预测正确时,\text{y}_i(wx_i+b)为正,
预测错误时,\text{y}_i(wx_i+b)为负,
即,网络越正确,L(w,b)越小,网络越错误,L(w,b)越大。
则我们要令L更小,只要往w和b的负梯度方向调整即可。

03.损失函数的梯度


可算得损失函数L中 w 和 b 的梯度如下:
(1) w的梯度

\begin{aligned} \nabla _w L(w,b) &= \nabla _w -\sum \limits_{i} \text{y}_i(wx_i+b) \\&= -\sum \limits_{i} \nabla _w\text{y}_i(wx_i+b) \\&= -\sum \limits_{i} \text{y}_ix_i \end{aligned}


(2) b的梯度

\begin{aligned} \nabla _b L(w,b) &= \nabla _b -\sum \limits_{i} \text{y}_i(wx_i+b) \\&=- \sum \limits_{i} \nabla _b\text{y}_i(wx_i+b) \\&= -\sum \limits_{i} \text{y}_i \end{aligned}

单样本时w,b的梯度  

感知机一般用单样本训练,
由上可算得对于单个样本x_i
 训练时,w,b的梯度为:

\nabla _w L(w,b) =-\text{y}_ix_i

\nabla _b L(w,b) =-\text{y}_i

04.算法流程  


感知机采用逐样本训练方法,

具体训练流程如下:
1、初始化
将w和b的元素全部初始化为0。
2、逐样本训练
逐个样本训练 w,b:
------如果训练样本的预测值与真实值不一致,则往负梯度方向更新w,b( 其中,lr为学习率):
----------  w = w + \text{lr}*\text{y}_i*x_i
----------  b = b + \text{lr}*\text{y}_i
3、检测是否终止训练
如果总体预测误差达到目标,或达到最大训练步数,则终止训练,否则重复2
误差的评估: 

\displaystyle \textbf{E} = \dfrac{1}{n} \sum\limits _{i}^{n}\begin{cases} 0 & \text{ if } \textbf{sign}(wx_i+b )= \text{y}_i\\ 1 & \text{ else } \end{cases}


4、输出结果
输出w,b和网络最终的预测误差

已被证明,在样本点可分的情况下,算法经过有限次迭代,感知机肯定能将样本完全分开。
证明可参考 李航-《统计学习方法》2.3.2节。

05.实现代码  


下面是根据以上算法流程,自己编写的一个感知机的实现Demo

  1. % 本代码展示一个感知机模型的训练DEMO
  2. % ----------训练数据-------------------
  3. X = [0 0 0.2 1 1 0.8; 0 1 0.5 0 1 0.3];
  4. y = [-1 -1 -1 1 1 1 ];
  5. %----------参数设置与常量计算-----------------
  6. [in,sn] = size(X);    % 输入个数与样本个数
  7. goal    = 0;          % 训练目标
  8. lr      = 0.1;        % 学习率
  9. epochs  = 100;        % 最大训练步数
  10. % --------初始化权重---------------
  11. w = zeros(1,in); % 初始化权重
  12. b = 0;           % 初始化阈值
  13. % ----------感知机训练---------------------
  14. for i = 1:epochs
  15.     % 逐样本训练
  16.     for j = 1:sn
  17.         cur_x = X(:,j);                 % 当前训练样本
  18.         cur_y = y(:,j);
  19.         py =  2*((w*cur_x+b)>=0)-1;     % 当前训练样本的预测值
  20.         if(py~=cur_y)
  21.             w = w + lr*cur_y*cur_x';
  22.             b = b + lr * cur_y;
  23.         end
  24.     end
  25.     % 如果误差达到目标,则退出训练
  26.     e   = sum(( 2*((w*X+b)>=0)-1 )~=y)/sn;      % 计算误差    
  27.     if e<=goal
  28.        break; 
  29.     end
  30. end
  31. % -------------绘制结果----------------------
  32. x_line = [min(X(1,:)),max(X(1,:))];
  33. y_line =(-w(1)*x_line-b)/w(2);
  34. plot(x_line,y_line)
  35. hold on
  36. plot(X(1,y==1),X(2,y==1),'bo')
  37. hold on
  38. plot(X(1,y==-1),X(2,y==-1),'k*')
  39. hold on
  40. axis([min(X(1,:))-1 max(X(1,:))+1 min(X(2,:))-1 max(X(2,:))+1]) 

结果如下

  在结果中可以看到,感知机模型把两类样本点完美地分开。


三、matlab中的感知机神经网络 

matlab中的感知机神经网络是由感知机演变而来,
它是一个两层的神经网络,只有输入层与输出层。

01.感知机神经网络的拓扑结构   


这里举例说明,
一个2输入3输出的感知机神经网络拓扑图如下:

输出层的激活函数支持hardlim和hardlims,两者的区别如下:

\text{hardlim}(x) = \left\{\begin{matrix} 1 & x\geqslant 0\\ 0 & x<0 \end{matrix}\right.

\text{hardlims}(x) = \left\{\begin{matrix} 1 & x\geqslant 0\\ -1 & x<0 \end{matrix}\right.


当输出层的激活函数为hardlim每个输出的输出值是0或1,
而当输出层的激活函数为hardlims每个输出的输出值是-1或1。
mamtlab中默认激活函数为hradlim

02.感知机神经网络的数学表达式


激活函数为hardlim时:

\text{y} = \left [ (Wx+b )\geqslant 0 \right ]


激活函数为hardlims时:

\text{y} = 2*\left [ (Wx+b )\geqslant 0 \right ] -1


由于matlab的默认激活函数为hardlim,
而hardlim和hardlims两者没有本质的区别,下面下我们只介绍hardlim。


03.辨识:与二分类感知机的区别  


(1) 上篇感知机介绍的为二分类,只有一个输出,而这里的神经网络支持多输出。                  
(2) matlab感知机神经网络默认使用的激活函数为hardlim,而上篇的二分类感知机是hardlims
总的来说,matlab的感知机神经网络默认输出格式为one-hot编码,即[0 1 0 0]这类的格式。

04.训练目标与损失函数 


重新强调,下面统一默认为hardlim激活函数,即输出为{0,1}。

感知机神经网络的训练目标-误差函数   
感知机的误差评估函数为预测错误样本个数的占比:

\displaystyle \textbf{E} = \dfrac{1}{m*n} \sum \limits _i^{m}\sum \limits _j^{n} \left ( |\text{y}_{ij}-p_{ij} |\right )


其中,
m:输出个数                                                 
n:样本个数                                                  
\text{y}_{ij}:第i个样本的第j个输出。                         
p_{ij}:网络对第i个样本第j个输出的预测值。    
感知机的训练目标就是找出一组w,b,使E最小化。

损失函数   
感知机神经网络的训练可以使用梯度下降法,
但由于误差评估函数,不方便求导,
所以先构造一个与误差评估函数相关的损失函数,
然后用损失函数的梯度来引导w,b的调整。
可以用以下函数作为损失函数,来引导w,b的迭代方向。

\displaystyle \textbf{ L}(w,b) = \sum \limits_{i} -(2*\text{y}_i-1)(wx_i+b)

05.损失函数的梯度 


可算得损失函数L中 w 和 b 的梯度如下:
(1) w的梯度
\begin{aligned} \nabla _w \textbf{L}(w,b) &= \nabla _w \sum \limits_{i} -(2*\text{y}_i-1)(wx_i+b) \\&= \sum \limits_{i} \nabla _w -(2*\text{y}_i-1)(wx_i+b) \\&= \sum \limits_{i} -(2*\text{y}_i-1)x_i \end{aligned}
(2) b的梯度
\begin{aligned} \nabla _b \textbf{L}(w,b) &= \nabla _b \sum \limits_{i} -(2*\text{y}_i-1)(wx_i+b) \\&= \sum \limits_{i} \nabla _b -(2*\text{y}_i-1)(wx_i+b) \\&= \sum \limits_{i} -(2*\text{y}_i-1)\end{aligned}

单样本时w,b的梯度   
感知机一般用单样本训练,
由上可算得对于单个样本x_i
 训练时,w,b的梯度为:

\nabla _w \textbf{L}(w,b) = -(2*\text{y}_i-1)x_i

\nabla _b \textbf{L}(w,b) = -(2*\text{y}_i-1)


上式也可以改写成如下形式:

\nabla _w \textbf{L}(w,b) = -(\text{y}_i-\text{p}_i)x_i

\nabla _b \textbf{L}(w,b) = -(\text{y}_i-\text{p}_i)

其中,\text{p}_i是网络对x_i的预测值。

06.算法流程


感知机采用逐样本训练方法,具体训练流程如下:
1、初始化
将w和b的元素全部初始化为0。

2、逐样本训练
逐个样本训练w,b:

w = w + ( \text{y}_i - p_i)*x_i

b = b+( \text{y}_i - p_i)


其中,yi为当前训练样本的真实y值,pi为网络对当前训练样本的预测值
3、检测是否终止训练
如果总体预测误差达到目标,或达到最大训练步数,则终止训练,否则重复2
误差的评估:

\displaystyle E = \dfrac{1}{m*n} \sum \limits _i^{m}\sum \limits _j^{n} \left ( |\text{y}_{ij}-p_{ij} |\right )


4、输出结果
输出 网络参数w,b 和网络最终的预测误差

07.代码实现-自己实现newp

我们细扒matlab神经网络工具箱newp的源码后,
去除冗余代码,重现简版newp代码,代码与newp的结果完全一致。
通过本代码的学习,可以完全细节的了解感知机神经网络的实现逻辑。

  1. function testPnet()
  2. %本代码来自bp.bbbdata.com
  3. %本代码模仿matlab神经网络工具箱的newp函数自写感知机神经网络,
  4. %代码主旨用于教学,供大家学习理解newp函数的内部机制与感知机神经网络原理
  5. %--------------------------------------------
  6. % ----------训练数据-------------------
  7. X = [0 0 1 1; 0 1 0 1];
  8. y = [0 1 0 1;1 0 0 0;0 0 1 0];
  9. %-----------参数设置-------------------
  10. epochs = 100;  % 迭代步数
  11. %---------调用自写函数进行训练---------
  12. %通过自己建立模型训练网络,获得w,b
  13. rand('seed',70);
  14. [w,b,e,Erc]=trainPnet(X,y,epochs);
  15. py = predictPnet(w,b,X); %用训练好的感知机预测类别
  16. % 自写函数的结果
  17. w
  18. b
  19. % -----调用工具箱进行训练--------------
  20. % 调用工具箱进行训练
  21. rand('seed',70);
  22. net = newp([0 1; -2 2],3);
  23. net.trainParam.epochs = epochs;
  24. [net,tr]  = train(net,X,y);
  25. % 工具箱的结果
  26. tool_w=net.IW{1}
  27. tool_b=net.b{1}
  28. % -------自写方法与工具箱的差异-----------------
  29. maxECompareNet = max([max(abs(w(:)-tool_w(:))),...
  30.     max(abs(b(:)-tool_b(:))),max(abs(Erc(:)-tr.perf(:)))]);
  31. disp(['自写代码与工具箱权重阈值的最大差异:',num2str(maxECompareNet)])
  32. end
  33. % ----感知机训练函数-----
  34. function [w,b,e,Erc]=trainPnet(X,y,epochs)
  35. %----------参数设置与常量计算-----------------
  36. [in,sn]=size(X);    % 输入个数与样本个数
  37. on     = size(y,1);  %输出个数
  38. goal =0;   %训练目标
  39. % ---------网络权重与相关变量初始化---------------
  40. w = zeros(on,in); %初始化权重
  41. b = zeros(on,1);  %初始化阈值
  42. py = predictPnet(w,b,X);  %预测训练样本
  43. e= sum(sum(abs(y -py)))/length(py(:)); % 计算误差
  44. Erc      = [e];   %记录误差
  45. % ----------网络权重训练---------------------
  46. for i = 1:epochs
  47.     % 逐样本训练
  48.     for j = 1:sn
  49.         % 计算预测误差
  50.         cur_x = X(:,j);                 % 当前训练样本
  51.         py    = predictPnet(w,b,cur_x); % 当前训练样本的预测值
  52.         e1    = y(:,j) - py;            % 当前训练样本的误差
  53.         
  54.         % 调整权重
  55.         w = w + e1*cur_x';              % 调整权重w
  56.         b = b+e1;                       % 调整阈值b
  57.     end
  58.     % 计算网络误差并记录
  59.     py  = predictPnet(w,b,X);                   % 网络的预测值
  60.     e   = sum(sum(abs( y -py)))/length(py(:));  % 网络的误差
  61.     Erc = [Erc,e];                              % 记录本次误差
  62.     
  63.     % 如果误差达到目标,则退出训练
  64.     if e<=goal
  65.         break;
  66.     end
  67. end
  68. end
  69. % ----感知机预测函数-----
  70. function y = predictPnet(w,b,x)
  71. y = (w*x+repmat(b,1,size(x,2)))>=0;
  72. end

运行结果共三部分
1. 自写代码求得的网络权重与阈值

2. 调用工具箱求得的网络权重与阈值

3. 自写代码与工具箱的结果对比


从运行结果可以看到,自写代码与工具箱的结果一样,说明扒出的逻辑与工具箱的一致。


四、matlab神经网络工具箱的感知机实现与说明


在实际使用中,我们更多时候是使用matlab自带的神经网络工具箱的newp来实现感知机神经网络,

下面我们学习工具箱的使用说明。

01. 简单Demo  


matlab工具箱使用感知机神经网络的Demo代码(2014b版matlab实测已跑通):

  1. %代码说明:newp的matlab工具箱使用Demo
  2. %来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2014b
  3. %-----------------------------------------------------
  4. % 训练数据
  5. X = [0 0 1 1; 0 1 0 1];
  6. y = [0 1 1 1;];
  7. %训练
  8. net = newp(X,y);             % 建立网络
  9. [net,tr]  = train(net,X,y);  % 训练网络
  10. %预测
  11. py = sim(net,X) %使用网络进行预测


02. 工具箱说明  


语法:
 net = newp(p,t,tf,lf)

描述:
感知机用于解决简单的(例如线性可分)分类问题。

入参说明
P: 用于训练的输入数据。每列代表一个样本,有多少个样本,就有多少列。
T:用于训练的输出数据。每列代表一个样本,有多少个样本,就有多少列。
TF:传递函数,默认为'hardlim',支持hardlim和hardlims。
LF:学习函数,默认为'learnp',支持learnp和learnpn。

备注:
感知机可以在有限步数内解决将线性可分的分类问题。如果输入变量较多,learnpn比learnp在训练速度上更加快。


相关文章

​《BP神经网络梯度推导》

​​​​​​《BP神经网络提取的数学表达式》

《一个BP的完整建模流程》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/442317
推荐阅读
相关标签
  

闽ICP备14008679号