感知机-算法原理与自实现
感知机
感知机神经网络代码实现
作者 : 老饼 日期 : 2022-06-22 15:00:17 更新 : 2022-06-29 01:28:33
本站原创文章,转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com


本文是笔者细扒matlab神经网络工具箱newp的源码后,

去除冗余代码,重现的简版newp代码,代码与newp的结果完全一致。

通过本代码的学习,可以完全细节的了解感知机神经网络的实现逻辑。


  01. 代码实现  


  代码简要描述  


本代码主要重现了matlab感知机神经网络newp的算法逻辑。
并通过一个用例,证明重写后的代码训练出来的权重、阈值与工具箱的训练结果一致。


matlab2014b亲测已跑通:



function testPnet()
%本代码来自bp.bbbdata.com
%本代码模仿matlab神经网络工具箱的newp函数自写感知机神经网络,
%代码主旨用于教学,供大家学习理解newp函数的内部机制与感知机神经网络原理
%--------------------------------------------
% ----------训练数据-------------------
X = [0 0 1 1; 0 1 0 1];
y = [0 1 0 1;1 0 0 0;0 0 1 0];
%-----------参数设置-------------------
epochs = 100;  % 迭代步数

%---------调用自写函数进行训练---------
%通过自己建立模型训练网络,获得w,b
rand('seed',70);
[w,b,e,Erc]=trainPnet(X,y,epochs);
py = predictPnet(w,b,X); %用训练好的感知机预测类别
% 自写函数的结果
w
b

% -----调用工具箱进行训练--------------
% 调用工具箱进行训练
rand('seed',70);
net = newp([0 1; -2 2],3);
net.trainParam.epochs = epochs;
[net,tr]  = train(net,X,y);

% 工具箱的结果
tool_w=net.IW{1}
tool_b=net.b{1}

% -------自写方法与工具箱的差异-----------------
maxECompareNet = max([max(abs(w(:)-tool_w(:))),...
    max(abs(b(:)-tool_b(:))),max(abs(Erc(:)-tr.perf(:)))]);
disp(['自写代码与工具箱权重阈值的最大差异:',num2str(maxECompareNet)])

end

% ----感知机训练函数-----
function [w,b,e,Erc]=trainPnet(X,y,epochs)
%----------参数设置与常量计算-----------------
[in,sn]=size(X);    % 输入个数与样本个数
on     = size(y,1);  %输出个数
goal =0;   %训练目标

% ---------网络权重与相关变量初始化---------------
w = zeros(on,in); %初始化权重
b = zeros(on,1);  %初始化阈值
py = predictPnet(w,b,X);  %预测训练样本
e= sum(sum(abs(y -py)))/length(py(:)); % 计算误差
Erc      = [e];   %记录误差

% ----------网络权重训练---------------------
for i = 1:epochs
    % 逐样本训练
    for j = 1:sn
        % 计算预测误差
        cur_x = X(:,j);                 % 当前训练样本
        py    = predictPnet(w,b,cur_x); % 当前训练样本的预测值
        e1    = y(:,j) - py;            % 当前训练样本的误差
        
        % 调整权重
        w = w + e1*cur_x';              % 调整权重w
        b = b+e1;                       % 调整阈值b
    end
    % 计算网络误差并记录
    py  = predictPnet(w,b,X);                   % 网络的预测值
    e   = sum(sum(abs( y -py)))/length(py(:));  % 网络的误差
    Erc = [Erc,e];                              % 记录本次误差
    
    % 如果误差达到目标,则退出训练
    if e<=goal
        break;
    end
end

end

% ----感知机预测函数-----
function y = predictPnet(w,b,x)
y = (w*x+repmat(b,1,size(x,2)))>=0;
end





  02. 代码运行结果解说    


运行结果共三部分


1. 自写代码求得的网络权重与阈值





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





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



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





  03. 代码结构说明  

代码主要包含了3个函数:


testPnet:测试用例主函数,直接运行时就是执行该函数。


1、数据:生成一个2输入3输出的训练数据,
2、用自写的函数训练一个感知机神经网络
3、使用工具箱newp训练一个感知机神经网络。
4、比较自写函数与工具箱训练结果是否一致


trainPnet:训练主函数。


训练一个感知机神经网络,相当于重写工具箱的newp函数,实现newp一样的功能。



predictPnet:预测主函数。


传入需要预测的X,与网络的权重矩阵,即可得到预测结果。





  End  








联系小饼