声明:本文部分代码和图文来自《老饼讲解-BP神经网络》:老饼|BP神经网络
好记性不如烂笔头,
这段时间学习了神经网络后,难免有些混乱,这里特地整理和梳理一下matlab中的各种神经网络和简要的DEMO
目录
一.BP神经网络
二.用于做分类的神经网络
2.1.感知机神经网络
2.2.LVQ神经网络
2.3.SOM神经网络
三.用于做数值预测的神经网络
3.1.径向基神经网络RBF
3.2.广义回归神经网络GRNN
3.3.概率神经网络PNN
四、时间序列神经网络
4.1 Elman神经网络
1.1.BP神经网络可以用于做数值预测,也可以用于做分类
bp神经网络是应用最广泛的一种神经网络,它的拓扑结构如下:
%来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2014b
x1 = [-3,-2.7,-2.4,-2.1,-1.8,-1.5,-1.2,-0.9,-0.6,-0.3,0,0.3,0.6,0.9,1.2,1.5,1.8]; % x1:x1 = -3:0.3:2;
x2 = [-2,-1.8,-1.6,-1.4,-1.2,-1,-0.8,-0.6,-0.4,-0.2,-2.2204,0.2,0.4,0.6,0.8,1,1.2]; % x2:x2 = -2:0.2:1.2;
y = [0.6589,0.2206,-0.1635,-0.4712,-0.6858,-0.7975,-0.8040,...
-0.7113,-0.5326,-0.2875 ,0,0.3035,0.5966,0.8553,1.0600,1.1975,1.2618]; % y: y = sin(x1)+0.2*x2.*x2;
inputData = [x1;x2]; % 将x1,x2作为输入数据
outputData = y; % 将y作为输出数据
setdemorandstream(88888);%指定随机种子,这样每次训练出来的网络都一样。
%使用用输入输出数据(inputData、outputData)建立网络,
%隐节点个数设为3.其中隐层、输出层的传递函数分别为tansig和purelin,使用trainlm方法训练。
net = newff(inputData,outputData,3,{'tansig','purelin'},'trainlm');
%设置一些常用参数
net.trainparam.goal = 0.0001; % 训练目标:均方误差低于0.0001
net.trainparam.show = 400; % 每训练400次展示一次结果
net.trainparam.epochs = 15000; % 最大训练次数:15000.
[net,tr] = train(net,inputData,outputData); % 调用matlab神经网络工具箱自带的train函数训练网络
simout = sim(net,inputData); % 调用matlab神经网络工具箱自带的sim函数得到网络的预测值
figure; % 新建画图窗口窗口
t=1:length(simout);
plot(t,y,t,simout,'r') % 画图,对比原来的y和网络预测的y
用BP神经网络做分类时的DEMO如下
%来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2012b
load crab_dataset
x = crabInputs;
t = crabTargets;
setdemorandstream(491218382);%指定随机种子,这样每次训练出来的网络都一样。
net = patternnet(10); %建立模式识别网络,隐层设为10个
[net,tr] = train(net,x,t); %将数据放到网络中训练
plotperform(tr) %画出训练记录
%%用检验数据检验网络的正确率
testX = x(:,tr.testInd);
testT = t(:,tr.testInd);
testY = net(testX);
testIndices = vec2ind(testY);
%% 画出混淆矩阵,并计算正确率
plotconfusion(testT,testY)
[c,cm] = confusion(testT,testY) %计算混淆矩阵
fprintf('Percentage Correct Classification : %f%%\n', 100*(1-c));
fprintf('Percentage Incorrect Classification : %f%%\n', 100*c);
figure
感知机神经网络主要用于做分类,感知机神经网络就是最原始的模型
感知机在matlab中使用newp来创建,DEMO代码如下:
%代码说明:newp的matlab工具箱使用Demo
%来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2014b
%-----------------------------------------------------
% 训练数据
X = [0 0 1 1; 0 1 0 1];
y = [0 1 1 1;];
%训练
net = newp(X,y); % 建立网络
[net,tr] = train(net,X,y); % 训练网络
%预测
py = sim(net,X) %使用网络进行预测
LVQ神经网络是Kohonen于1989年提出基于竞争网络的学习矢量量化网络,主要用于做聚类。
LVQ就是先随机给一些类别初始化一些判别中心,然后通过调整类别中心,使它们更好地识别训练样本,在训练完成后,就可以将类别中心提取出来,作为类别判别的依据
LVQ神经网络在matlab如下实现
%代码说明:LVQ的matlab工具箱使用Demo
%来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2014b
%-----------------------------------------------------
%数据准备
P = [-3 -2 -2 0 0 0 0 +2 +2 +3; ...
0 +1 -1 +2 +1 -1 -2 +1 -1 0]; % 输入数据
Tc = [1 1 1 2 2 2 2 1 1 1]; % 输出类别
T = ind2vec(Tc); % 将输出转为one-hot编码(代表类别的01向量)
%网络训练
net = newlvq(P,4,[.6 .4]); % 建立一个LVQ神经网络
net = train(net,P,T); % 训练神经网络
%预测
Y = sim(net,P); % 预测(one-hot形式)
Yc = vec2ind(Y); % 将one-hot编码形式转回类别编号形式
SOM神经网络主要用于做分类,它来源于Kohonen规则聚类,但引入了隐层节点之间的拓扑结构
SOM神经网络在matlab中可以使用solforgmap来创建,它的demo代码如下:
% 本demo展示用matlab工具箱训练一个SOM神经网络
% demo来自matlab2014帮助文档
x = simplecluster_dataset; % 加载matlab自带的分类数据
net = selforgmap([8 8]); % 建立一个SOM神经网络
net = train(net,x); % 训练网络
view(net) % 查看网络
y = net(x); % 用训练好的网络进行预测
classes = vec2ind(y); % 将预测结果由one-hot格式转为类别索引
径向基神经网络由J.Moody和C.Darken在20世纪80年代末提出,它是一种基于数学原理的神经网络,可以逼近任意曲线
径向基神经网络的本质就是用径向曲线来拼凑出目标曲线
matlab对径向基神经网络提供了两种求解方式:精确求解和OLS求解
精确求解时采用newrbe函数构建网络,OLS求解时使用newrb
两者的区别在于,
(1)newrbe可以0误差,但网络较复杂,模型较大
(2)newrb可以根据目标误差,在newrbe中挑选部分节点来构成网络,所以newrb的模型较小一些
RBF的精确求解可以用newrbe来实现,DEMO代码如下:
%代码说明:径向基newrbe的matlab工具箱使用Demo
%来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2014b
%-----------------------------------------------------
%----数据准备----
x1 = 1:0.2:10;
x2 = -5:0.2:4;
X = [x1;x2]; % 输入数据,注意中间是分号
Y = sin (X(1,:))+X(2,:); % 输出数据
%----网络训练----
net = newrbe(X,Y,2); % 以X,Y建立径向基网络,径向基的spread=2
simY = sim(net, X); % 用建好的网络拟合原始数据
%----结果对比----
figure(1);
t = 1:size(Y,2);
plot(t,Y,'*',t,simY,'r')
RBF的OLS求解可以用newrb来实现,DEMO代码如下:
%代码说明:径向基newrb的matlab工具箱使用Demo
%来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2014b
%-----------------------------------------------------
%----数据准备----
x1 = 1:0.2:10;
x2 = -5:0.2:4;
X = [x1;x2]; % 输入数据,注意中间是分号
Y = sin (X(1,:))+X(2,:); % 输出数据
%----网络训练----
net = newrb(X, Y, 0, 2); % 以X,Y建立径向基网络,目标误差为0,径向基的spread=2
simY = sim(net, X); % 用建好的网络拟合原始数据
%----结果对比----
figure(1);
t = 1:size(Y,2);
plot(t,Y,'*',t,simY,'r')
广义回归神经网络GRNN全称为(General Regression Neural Network)
它由美国Donald F.Specht于1991年提出,是一种基于非线性的回归理论的神经网络
广义回归也是使用径向网络来构成,只是它与RBF的原理出发点不同
广义回归神经网络在matlab中可以使用 newgrnn来实现
%代码说明:径向基newgrnn的matlab工具箱使用Demo
%来自《老饼讲解神经网络》bp.bbbdata.com ,matlab版本:2014b
%-----------------------------------------------------
%----数据准备----
x1 = 1:0.2:10;
x2 = -5:0.2:4;
X = [x1;x2]; % 输入数据,注意中间是分号
Y = sin (X(1,:))+X(2,:); % 输出数据
%----网络训练----
net = newgrnn(X,Y); % 网络建立与训练
simY = sim(net, X); % 用建好的网络拟合原始数据
%----结果对比----
figure(1);
t = 1:size(Y,2);
plot(t,Y,'*',t,simY,'r')
概率神经网络全称为Probabilistic Neural Network
它由D.F.Speeht在1989年提出,是径向基网络的一个分支
它与广义神经网络类似,但概率神经网络仅用于模式识别(分类)
在matlab中,概率神经网络可用newpnn来实现,DEMO代码如下
% 训练数据
P = [1 2 3 4 5 6 7]; % 输入数据
Tc = [1 2 3 2 2 3 1]; % 输出数据:类别编号
T = ind2vec(Tc); % 将类标转换为onehot编码格式
%设计一个PNN神经网络,并测试
net = newpnn(P,T); % 生成一个概率神经网络
Y = sim(net,P) % 用网络进行预测
Yc = vec2ind(Y) % 将预测结果转为类别编号
Elman神经网络是 J. L. Elman于1990年提出的一种用于时序的神经网络,也就是后世所称的RNN神经网络
ELMAN神经网络就是三层BP神经网络,但它每次会把上一时刻的隐节点当作当前时刻的输入
这是序列数据的特有模型
ELman神经网络在matlab中可以用newelm来实现,DEMO代码如下:
% 本代码展示如何用matlab训练一个Elman神经网络
% 代码主旨用于教学,供大家学习理解如何用matlab训练一个Elman神经网络
% 转载请说明来自 《老饼讲解神经网络》 bp.bbbdata.com
% 生成输入输出数据
X = -5:0.3:5; % 用于训练网络的输入数据
y = sin(X); % 用于训练网络的输出数据
rand('seed',408); % 指定随机种子,这样每次训练出来的网络都一样。
net = newelm(X,y,6,{'tansig','purelin'}); % 新建一个elman网络
net.trainparam.goal = 0.00001; % 设置训练目标
net.trainparam.epochs = 2000; % 设置最大训练次数.
% ----------网络训练---------------
% 在训练时一定要将数据转为序列数据,
% 如果是矩阵格式,工具箱会认为每个数据是独立的
Xseq = con2seq(X); % 将输入转成序列格式
Yseq = con2seq(y); % 将输出转成序列格式
[net,tr] = train(net,Xseq,Yseq); % 将输入输出数据进行训练
% ----------网络预测---------------
% 注意,在预测时也必须传入序列数据,
% 如果传入矩阵格式,工具箱会认为只是一个时刻的数据,而不是多个时刻的数据,
% 也就是说,网络会对每个数据进行独立预测,它不会把上个数据的隐节点作为延迟输入传给下个数据
py = sim(net,Xseq); % 用训练好的网络进行预测,
py = cell2mat(py) % 将预测结果转为矩阵格式
plot(X,y,X,py,'*')
legend('原始数据','预测结果')
整理不易,望点赞~