老饼讲解-神经网络
自实现-径向基神经网络
广义回归与概率神经网络
概率神经网络-自实现代码
作者 : 老饼 日期 : 2022-06-09 04:49:33 更新 : 2022-06-29 01:28:03
本站原创文章,转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com



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

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

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



  01. 代码结构  

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


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


1、数据:生成一个2输入1输出的训练数据,
2、用自写的函数构建一个概率神经网络,与用网络进行预测。
3、使用工具箱newpnn训练一个概率神经网络。比较自写函数与工具箱训练结果是否一致(比较测试数据的输出结果是否一致)


trainPnnNet:训练主函数。


训练一个概率神经网络。



predictPnnNet:预测主函数。


传入需要预测的X,与网络的权重矩阵,即可得到预测结果。
PASS :    概率神经网络和广义回归神经网络非常像.但概率神经网络只用于做分类.应该注意的两点:
(1) 概率神经网络是用来做分类的,若果输入是1 2 3这种类标,必须转为one-hot形式,例如类别为2时,转为[0 1 0]这样的向量.
(2) 虽然概率神经网络通过隐节点得到径向基的值后,需要作归一化,但是由于它不会影响最后的竞争比较结果, 所以在计算时可以不对径向基进行归一化.





  02. 代码运行结果解说  


    1、网络的权重与阈值    




    2、与工具箱结果的比较    



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






  03.算法流程  

   1、广义神经网络的(最小)输入输出如下:  



   ● 需要的输入   

● 训练数据:
X:训练数据的输入 
y:训练数据的输出
● 训练参数:
spread:一个用于控制径向基的肥瘦的参数。


    ● 需要的输出(待求的网络参数)     

(1) 输入到隐层的权重:W21   
(2) 隐层阈值:B2                    
(3) 隐层到输出层的权重:W32


   2、广义回归算法流程   



● 网络构建阶段

广义神经网络,不需要任何训练,只需要把输入数据存成网络的参数即可,
W21(输入层-->隐层权重):
用X作为w21即可                                 
B2(隐层阈值):用spread生成, ​  
W32(隐层-->输出层层权重):用y作为w32即可。                           


●  网络的预测

 计算y的公式格式参考如下Demo:





1.计算各个隐节点的输出:即计算各个exp的值。先计算它到各个W21(也即训练样本的X)的距离,再将距离乘以B2(即a),再经激活函数转换(即套上径向基函数),这样就得到隐节点的输出。
2.计算输出:先计算判别值,即W32(即训练数据的y)乘以隐节点(即y乘以权重),竞争后就是最终的输出。






  四.代码实现  

matlab2014b亲测已跑通:

function testPnnNet()
%本代码来自 老饼讲解神经网络 bp.bbbdata.com
%本代码模仿matlab神经网络工具箱的newpnn神经网络,用于训练《概率神经网络》,
%代码主旨用于教学,供大家学习理解newpnn神经网络原理

%--------生成训练数据-------------------
%%生成训练数据
X = [1 2 3 4 5 6 7;7 6 5 4 3 2 1 ];
Class = [1 2 3 2 2 3 1];       % 所属类别
y = full(ind2vec(Class));      % 转为one-hot编码,这里为了方便查看,不使用稀疏矩阵
test_x = [3 5]'; %测试数据
%---------参数预设----------------------
spread = 1;  %扩展系数

%------调用自写Pnn函数获得广义回归神经网络-----------------
[w21,b2,w32] = trainPnnNet( X,y,spread ) %建立网络
py = predictPnnNet(w21,b2,w32,test_x); %自编网络的输出
py  = vec2ind(py )
%------调用matlab神经网络工具箱训练概率神经网络
net = newpnn(X,y,spread);   % 用工具箱设计概率回归网络
pyByBox  =  sim(net, test_x); % 工具箱的输出  
pyByBox  = vec2ind(pyByBox )


testResult = isequal( py, pyByBox);  
disp(['testResult = ',num2str(testResult)]);

web('bp.bbbdata.com')
end

% 概率神经网络的生成函数
function [w21,b2,w32] = trainPnnNet(X,Y,spread)
%生成概率神经网络只要将输入输出存到w21,w32中,
%再用spread生成影响径向基宽度的B1就可以
Q = size(X,2);
w21 = X'; 
w32 = Y;
b2 = ones( Q, 1)*sqrt( -log(.5))/spread;
end

% 概率神经网络的预测函数
function y = predictPnnNet(w21,b2,w32,X)
y = [];
for i = 1:size(X,2)
  cur_x = X(:,i);
  hv    = b2.*sqrt(sum((ones(size(w21,1),1)*cur_x' - w21).^2,2));    % 计算隐节点的值
  ha    = exp(-(hv.*hv));                                            % 计算隐节点激活值
  g = w32*ha;                                                        % 计算输出(判别值)  
  [~,max_idx]    = max(g);                                           % 获取最大判别值的索引
  cur_y          = g*0;                                              % 置0
  cur_y(max_idx) = 1 ;                                               % 将竞争成功的置1  
  y     = [y,cur_y];
end
end




  结束语  


概率神经网络最需要记得的是,它只用来做分类,若果输出是标签型数据(1 2 3),一定要转为one-hot编码([1 0 0],[0 1 0],[0 0 1]).









 End 








联系小饼