深度学习之BP神经网络案例
1、知识点:
A、BP神经网络:信号是前向传播,误差是反向传播,BP是算法,它不代表神经网络的结构;
B、BP神经网络是有导师学习的神经网络,在训练的时候,需要指定输入和输出,让它知道这个输入对应这个输出,让它清楚每次训练的过程,然后他的神经元的输出和理想值目标有多大的误差,这样才会有误差反向传播这个过程;
C、MATLAB里怎么创建神经网络包括设置他的参数:包括训练,包括仿真预测,这个过程需要了解;
D、在训练之前有必要对数据进行归一化处理,为什么要归一化,归一化的方法有哪些,需要掌握的知识点。
神经网络的学习规划又称为神经网络的训练算法,用来计算更新神经网络的权值和阈值。学习规则有两大类别:有导师学习和无导师学习。在有导师学习中,需要为学习规则提供一系列正确的网络输入/输出对(即训练样本),当网络输入时,将网络输出与对应的期望值进行比较,然后应用学习规则调整权值和阈值,使网络的输出接近于期望值。而无导师学习中,权值和阈值调整只与网络输入有关系,没有期望值,这类算法大多用聚类算法,将输入模式归类于有限的类别。(有导师学习神经网络:BP神经网络和RBF神经网络)
2、BP神经网络的结构是一种典型的多层前向型神经网络,具有一个输入层,数个隐含层(可以是一层,也可以是多层)和一个输出层。层与层之间采用全连接的方式,同一层的神经元之间不存在相互连接。
3、BP神经网络的学习算法(传播和权值更新):误差反向传播算法是典型的有导师指导的学习算法,其基本思想是对一定数量的样本对(输入和期望输出)进行学习,即样本特征(训练集)的输入送至网络输入层的各个神经元,经隐含层和输出层的计算后(映射),输出层各个神经元输出对应的预测值;若预测值与期望输出之间的误差不满足精度要求(阈值)时,就进行误差反向传播,即从输出层反向传播该误差,利用这个误差值来计算前一层的误差(误差计算进行到第二层为止),从而进行权值和阈值的调整,使得网络的输出和期望输出间的误差逐渐减小,直至满足精度要求。其中,权值更新:运用梯度下降法,即沿着梯度下降最快的方向——负梯度方向,进行修正。
4、BP网络的精髓:将网络的输出与期望输出间的误差归结为权值和阈值的“过错”,通过方向传播把误差“分摊”给各个神经元的权值和阈值。此处和线性拟合的误差进行比较。
5、BP网络学习算法的指导思想是权值和阈值的调整要沿着误差函数下降最快的方向——负梯度方向
6、BP神经网络的MATLAB工具箱函数
(1)归一化函数——mapminmax
函数mapminmax用于将值归一化到指定的范围内,一般是[-1, 1],其调用格式为
[Y, PS] = mapminmax(X, YMIN, YMAX)
其中,Y归一化后的输出结果;PS是训练样本的数据的映射;X为要归一化的函数(测试样本);YMIN为归一化后的最小值;YMAX为归一化后的最大值。
Y = mapminmax(‘apply’, X, PS),应用PS归一化的信息,对Test集(X)进行归一化
反归一化:
X = mapminmax(‘reverse’, Y, PS),是预处理之后的数据进行反转得到原始数据
(2)BP网络创建函数——newff(Create feed-forward backpropagation network)
函数 newff 用于创建一个BP神经网络,其调用格式为 # feed-forward 前馈
net = newff(P, T, [S1 S2 ... S(N-1)], {TF1, TF2 ... TFN}, BTF, BLF, PF, IPF, OPF, DDF)
其中,P为输入向量;T为输出向量;Si为隐含层神经元数目(默认为空);TFi为传递函数,(默认隐含层传递函数为tansig(双极S型函数),输出层传递函数为purelin);BTF为网络训练函数(默认为trianlm);BLF为网络权值/阈值学习函数(默认为learngdm);PF为性能函数(默认为mse(误差平方函数));IPE为输入处理函数(默认为{‘fixunknowns’,‘removeconstantrows’,‘mapminmax’});OPF为输出处理函数(默认为{‘removeconstantrows’,‘mapminmax’});DDF为数据划分函数(默认为‘dividerand’)
(3)训练函数——trian
函数 train 用于训练已经创建好的BP神经网络,其调用格式为
[net, tr, Y, E, Pf, Af] = train(net, P, T, Pi, Ai)
其中,net为训练前及训练后的网络;P为网络输入向量;T为网络目标向量(默认为0);Pi为初始的输入层延迟条件(默认为0);Ai为初始的输出层延迟条件(默认为0);tr为训练记录(包含步数及性能);Y为网络输出向量;E为网络误差向量;Pf为最终的输入层延迟条件;Af为最终是输出层延迟条件。
(4)预测函数——sim
函数 sim 用于利用已经训练好的BP神经网络进行仿真预测,其调用格式为
[Y, Pf, Af, E, perf] = sim(net, P, Pi, Ai, T)
其中,net为训练好的网络;P为网络输入向量;Pi为初始的输入层延迟条件(默认为0);Ai为初始的隐藏层延迟条件(默认为0);T为网络目标向量(默认为0);Y为网络输出向量;Pf为最终的输入层延迟条件;Af为最终的隐含层延迟条件;E为网络误差向量;perf为网络的性能
7、参数对BP神经网络性能的影响
(1)隐藏层神经元节点个数
(2)激活函数类型的选择
(3)学习率
(4)初始权值和阈值
(5)如何选取好的神经元个数的方法(或者换个问题能适应训练集并不代表能够适应一般情况,所以我们需要选择交叉验证集来选择模型。)
(1)交叉验证(cross validation)=训练集(training set)(训练|经验误差)+验证集(validation set)+测试集(泛化误差)(testing set)
交叉验证先将数据集D划分为k个大小相似的互斥子集。每个子集Di都尽可能保持数据分布的一致性,即从D中通过分层采样得到。然后,每次用k-1个子集的并集作为训练集+,余下的那个子集作为测试集;这样就可获得k组训练|测试集,从而可进行k次训练和测试,最终返回k次测试结果的均值(k折交叉验证)。K折交叉验证通常要随机使用不同的划分重复p次,最终的评估结果是这p次k折交叉验证结果的均值。(((((随机划分一般使用60%+20%+20%的分配方式。
- 使用训练集训练出10个模型
- 用10个模型分别对交叉验证集计算得出交叉验证误差(代价函数的值)
- 选取代价函数数值最小的模型
- 用步骤c中选出的模型对测试集计算得出推广误差(代价函数的值)
lamda值较小时(对应着训练集误差小),是方差|过拟合问题,,反之亦然。
1、尝试获取更多的训练实例——解决高方差|过拟合
2、尝试减少特征的数量——解决高方差|过拟合
3、尝试增加正则化程度lamda——解决高方差|过拟合
4、尝试获得更多的特征数量——解决高偏差|欠拟合
5、尝试增加特征多项式的特征——解决高偏差|欠拟合
6、尝试减小正则化程度lamda——解决高偏差|欠拟合
(2)留一法(Leave one out, LOO)(适合少量样本)
假设数据集中包含m个样本,若令k=m,则得到了交叉验证法的一个特例,它不受随机样本划分方式的影响,因为m个样本只有唯一的方式划分为m个子集——每个子集包含一个样本。
执行newff函数创建网络:
functions:
adaptFcn: 'adaptwb'
adaptParam: (none)
derivFcn: 'defaultderiv'
divideFcn: 'dividerand'
divideParam: .trainRatio, .valRatio, .testRatio
divideMode: 'sample'
initFcn: 'initlay'
performFcn: 'mse' %均方根误差,性能参数
performParam: .regularization, .normalization
plotFcns: {'plotperform', plottrainstate,
plotregression}
plotParams: {1x3 cell array of 3 params}
trainFcn: 'trainlm'
trainParam: .showWindow, .showCommandLine, .show, .epochs,
.time, .goal, .min_grad, .max_fail, .mu, .mu_dec,
.mu_inc, .mu_max
输入层与隐含层的连接权值
weight and bias values:
IW: {2x1 cell} containing 1 input weight matrix %输入层与隐含层的连接权值
LW: {2x2 cell} containing 1 layer weight matrix %隐含层与输出层的连接权值
b: {2x1 cell} containing 2 bias vectors %阈值
Doc traingdx 神经网络的训练方法:traingd | traingda | traingdm | trainlm:(gd)梯度下降法|(gda)带自适应学习率的梯度下降法|(gdm)带动量和自适应的梯度下降达|LM算法
程序代码;
%% I. 清空环境变量
clear all
clc
%% II. 训练集/测试集产生
%%
% 1. 导入数据
load spectra_data.mat
%%
% 2. 随机产生训练集和测试集
temp = randperm(size(NIR,1)); %size(NIR, 1)返回样本数;randperm产生由1-60的随机排列的数列
% 训练集——50个样本
P_train = NIR(temp(1:50),:)'; %转置,保证列代表训练集的样本个数,行代表变量特征的个数
T_train = octane(temp(1:50),:)';
% 测试集——10个样本
P_test = NIR(temp(51:end),:)';
T_test = octane(temp(51:end),:)';
N = size(P_test,2); %取出测试集样本的个数
%% III. 数据归一化
[p_train, ps_input] = mapminmax(P_train,0,1); % 对训练集的输入样本进行归一化
p_test = mapminmax('apply',P_test,ps_input); %应用归一化的信息(ps_input)将测试集输入样本归一化
[t_train, ps_output] = mapminmax(T_train,0,1); % 对训练集的输出也归一化
%% IV. BP神经网络创建、训练及仿真测试
%%
% 1. 创建网络
net = newff(p_train,t_train,9); % 隐含层神经元个数为9,这里是单隐含层
%%
% 2. 设置训练参数
net.trainParam.epochs = 1000; % 迭代次数
net.trainParam.goal = 1e-3; % 训练目标,均方根误差小于0.001
net.trainParam.lr = 0.01; % 学习率
%%
% 3. 训练网络
net = train(net,p_train,t_train);
%%
% 4. 仿真测试
t_sim = sim(net,p_test);
%%
% 5. 数据反归一化
T_sim = mapminmax('reverse',t_sim,ps_output);
%% V. 性能评价
%%
% 1. 相对误差error
error = abs(T_sim - T_test)./T_test;
%%
% 2. 决定系数R^2
R2 = (N * sum(T_sim .* T_test) - sum(T_sim) * sum(T_test))^2 / ((N * sum((T_sim).^2) - (sum(T_sim))^2) * (N * sum((T_test).^2) - (sum(T_test))^2));
%%
% 3. 结果对比
result = [T_test' T_sim' error']
%% VI. 绘图
figure
plot(1:N,T_test,'b:*',1:N,T_sim,'r-o')
legend('真实值','预测值')
xlabel('预测样本')
ylabel('辛烷值')
string = {'测试集辛烷值含量预测结果对比';['R^2=' num2str(R2)]};
title(string)