BP神经网络基础知识及简单拟合实例
- BP神经网络结构
- 前向计算
- 误差反向传播
- 梯度下降法
- 输出层参数调节
- 隐含层参数调节
- BP神经网络拟合实例
BP神经网络结构
BP神经网络(Back Propagation)是一种多层神经网络,其误差是反向传播的,因此称为BP神经网络。
BP神经网络包括输入层、隐含层和输出层三层,通常来说,隐含层的激活函数为
输出层的激活函数为
前向计算
我们记BP神经网络具有n个输入层神经元,隐含层有个神经元,输出层有个神经元。其隐含层权值矩阵为,偏置向量为,输出层权值矩阵为,偏置向量为。
BP神经网络的前向计算过程可以分为:隐含层的输出计算和输出层的输出计算。
我们记隐含层的输出为,输出层的输出为。
一个神经元的计算过程包括两部分:
- 输入的线性组合
- 激活函数的计算
隐含层的输入为神经网络的输入,其输出为
在matlab中,我们可以运用其矩阵运算来很方便的计算上式。
输出层的输入为隐含层的输出,其输出为
误差反向传播
梯度下降法
通过有效的训练,BP神经网络可以具有逼近任何非线性函数的能力。定义神经网络的估计误差均方差
其中,为期望的输出,为神经网络对输出的预测(或者说估计)。
神经网络的训练过程为,通过误差不断调整神经网络的参数(权值和偏移量),使得网络的估计误差均方差最小。
梯度下降法便是一种最为常用的寻找目标函数(即误差均方差函数)的方法。其基本原理为,沿着目标函数的梯度方向,目标函数是下降最快的。
输出层参数调节
基于上文,我们可以知道,调节权值矩阵的最快方法为
可以将上式表示为矢量形式,对权值矩阵的一整行进行操作,记权值矩阵的第行为,可知,此行元素通过影响第个输出,进而影响到最后的误差。权值矩阵第行的更新值为
可以通过链式法则来计算,即偏微分如下形式
那么,可以得到,输出层权值矩阵第行的更新律为
类似的,可以得到偏移量的更新律为
隐含层参数调节
隐含层参数矩阵和偏移量的更新方法是一样的,同样是对误差平方差进行求偏导得到,但是要复杂很多。权值矩阵的第行是通过隐含层所有神经元来影响最终的网络输出的,因此,其更新律为
表示为矩阵运算形式为
其中,, 为对角阵。
类似的,偏移量的更新律只与权值相差一个因子
化为矩阵运算形式为
BP神经网络拟合实例
采用BP神经网络对正弦函数进行拟合。网络结构设置为1-20-1,代码如下
% 训练简单的BP神经网络来拟合,自己写训练算法
clear,clc
%% 生成训练数据
ts = 0.01;
u1 = 0;
y1 = 0;
for k=1:1000
u(k) = k*ts;
y(k) = sin(u(k));
end
n = length(u);
训练算法主体部分
%% 训练算法
% 采用的BP神经网络为1-20-1的结构
yita = 0.1; %训练速度
num_h = 20;
w1 = rand(num_h,1);
% w1 = ones(num_h,1);
w2 = rand(num_h,1);
% w2 = ones(num_h,1);
b1 = zeros(num_h,1);
b2 = 0;
e_tol = 1e-3;
e = e_tol;
cnt = 1;
while cnt<10000 && e>=e_tol
% 打乱数据
idx_rand = randperm(n);
x_train = y(idx_rand); %网络输出
u_train = u(idx_rand); %网络输入
e = 0;
for i=1:400
%神经网络前向计算
for j = 1:num_h
H_input(j) = u_train(i)*w1(j)+b1(j);
H_output(j) = logsig(H_input(j));
end
Output(i) = dot(H_output,w2)+b2;
%误差反向传播
Error(i) = x_train(i) - Output(i);
for j=1:num_h
Delta_w2(j) = yita*Error(i)*H_output(j);
Dlogsig(j) = H_output(j)*(1-H_output(j));
Delta_w1(j) = yita*Error(i)*w2(j)*Dlogsig(j)*u_train(j);
w1(j) = w1(j)+Delta_w1(j);
w2(j) = w2(j)+Delta_w2(j);
b1(j) = b1(j) + yita*Error(i)*w2(j)*Dlogsig(j);
end
b2 = b2 + yita*Error(i);
e = e + Error(i)^2/2;
end
e = e/400;
e_store(cnt) = e;
cnt = cnt+1;
end
检测训练结果,并进行可视化
%% 检验训练结果
for i = 1:n
% k = randi(1000);
u_test = u(i);
x_test = y(i);
for j=1:num_h
H_input_test(j) = u_test*w1(j)+b1(j);
H_output_test(j) = logsig(H_input_test(j));
end
Output_test(i) = dot(H_output_test,w2)+b2;
% Output_test(i) = net_BP(u_test(i),w1,w2,b1,b2);
Error_test(i) = x_test-Output_test(i);
end
time = u;
figure(2)
plot(time(1:n),y(1:n),'r');
hold on
plot(time(1:n),Output_test,'b--');
hold on
plot(time(1:n),Error_test,'g-.');
legend('train','test','error');
神经网络拟合结果如下