BP神经网络结构
BP神经网络(Back Propagation)是一种多层神经网络,其误差是反向传播的,因此称为BP神经网络。
BP神经网络包括输入层、隐含层和输出层三层,通常来说,隐含层的激活函数为
f
1
(
x
)
=
1
1
+
e
−
x
f_1(x) = \frac {1}{1+e^{-x}}
f1(x)=1+e−x1
输出层的激活函数为
f
2
(
x
)
=
x
f_2(x)=x
f2(x)=x
前向计算
我们记BP神经网络具有n个输入层神经元,隐含层有
s
1
s_1
s1个神经元,输出层有
s
2
s_2
s2个神经元。其隐含层权值矩阵为
W
1
∈
R
s
1
×
u
W_1\in R^{s_1\times u}
W1∈Rs1×u,偏置向量为
b
1
∈
R
s
1
b_1\in R^{s_1}
b1∈Rs1,输出层权值矩阵为
W
2
∈
R
s
2
×
s
1
W_2 \in R^{s_2\times s_1}
W2∈Rs2×s1,偏置向量为
b
1
∈
R
s
2
b_1\in R^{s_2}
b1∈Rs2。
BP神经网络的前向计算过程可以分为:隐含层的输出计算和输出层的输出计算。
我们记隐含层的输出为
a
∈
R
s
1
a\in R^{s_1}
a∈Rs1,输出层的输出为
y
∈
R
s
2
y\in R^{s_2}
y∈Rs2。
一个神经元的计算过程包括两部分:
- 输入的线性组合
- 激活函数的计算
隐含层的输入为神经网络的输入
u
∈
R
n
u\in R^{n}
u∈Rn,其输出为
a
=
f
1
(
W
1
u
+
b
1
)
a=f_1(W_1u+b_1)
a=f1(W1u+b1)
在matlab中,我们可以运用其矩阵运算来很方便的计算上式。
输出层的输入为隐含层的输出
a
a
a,其输出为
y
=
f
2
(
W
2
a
+
b
2
)
y=f_2(W_2a+b_2)
y=f2(W2a+b2)
误差反向传播
梯度下降法
通过有效的训练,BP神经网络可以具有逼近任何非线性函数的能力。定义神经网络的估计误差均方差
E
=
1
2
∑
i
=
1
s
2
e
i
2
=
1
2
∑
i
=
1
s
2
(
y
d
−
y
)
2
E =\frac{1}{2}\sum_{i=1}^{s_2}e_i^2= \frac{1}{2} \sum_{i=1}^{s_2}(y_d-y)^2
E=21i=1∑s2ei2=21i=1∑s2(yd−y)2
其中,
y
d
y_d
yd为期望的输出,
y
y
y为神经网络对输出的预测(或者说估计)。
神经网络的训练过程为,通过误差不断调整神经网络的参数(权值和偏移量),使得网络的估计误差均方差最小。
梯度下降法便是一种最为常用的寻找目标函数(即误差均方差函数
E
E
E)的方法。其基本原理为,沿着目标函数的梯度方向,目标函数是下降最快的。
输出层参数调节
基于上文,我们可以知道,调节权值矩阵
W
2
W_2
W2的最快方法为
Δ
W
2
i
j
=
−
η
∂
E
∂
W
2
i
j
\Delta W_{2ij} = -\eta \frac{\partial E}{\partial W_{2ij}}
ΔW2ij=−η∂W2ij∂E
可以将上式表示为矢量形式,对权值矩阵的一整行进行操作,记权值矩阵
W
2
W_2
W2的第
i
(
i
=
1
,
2
,
.
.
.
s
2
)
i(i=1,2,...s_2)
i(i=1,2,...s2)行为
W
2
i
0
W_{2i0}
W2i0,可知,此行元素通过影响第
i
i
i个输出,进而影响到最后的误差。权值矩阵
W
2
W_2
W2第
i
i
i行的更新值为
Δ
W
2
i
0
=
−
η
∂
E
∂
W
2
i
0
\Delta W_{2i0} = -\eta \frac{\partial E}{\partial W_{2i0}}
ΔW2i0=−η∂W2i0∂E
可以通过链式法则来计算,即偏微分如下形式
∂
E
∂
W
2
i
0
=
∂
E
∂
e
i
∂
e
i
∂
f
2
∂
f
2
∂
W
2
i
0
=
−
e
i
f
2
′
a
T
\frac{\partial E}{\partial W_{2i0}}=\frac{\partial E}{\partial e_i} \frac{\partial e_i}{\partial f_2} \frac{\partial f_2}{\partial W_{2i0}}=-e_if_2'a^T
∂W2i0∂E=∂ei∂E∂f2∂ei∂W2i0∂f2=−eif2′aT
那么,可以得到,输出层权值矩阵
W
2
W_2
W2第
i
i
i行的更新律为
Δ
W
2
i
0
=
η
e
i
f
2
′
a
T
\Delta W_{2i0} = \eta e_if_2'a^T
ΔW2i0=ηeif2′aT
类似的,可以得到偏移量
b
2
b_2
b2的更新律为
Δ
b
2
i
=
η
e
i
f
2
′
\Delta b_{2i} = \eta e_if_2'
Δb2i=ηeif2′
隐含层参数调节
隐含层参数矩阵和偏移量的更新方法是一样的,同样是对误差平方差进行求偏导得到,但是要复杂很多。权值矩阵
W
1
W_1
W1的第
i
i
i行是通过隐含层所有神经元来影响最终的网络输出的,因此,其更新律为
Δ
W
1
j
0
=
−
η
∑
k
=
1
s
2
(
∂
E
∂
e
k
∂
e
k
∂
f
2
∂
f
2
∂
a
j
∂
a
j
∂
W
1
j
0
)
=
η
f
2
′
u
∑
k
=
1
s
2
(
e
k
W
2
k
j
)
f
1
′
\Delta W_{1j0} = -\eta \sum_{k=1}^{s_2}(\frac{\partial E}{\partial e_k} \frac{\partial e_k}{\partial f_2} \frac{\partial f_2}{\partial a_j} \frac{\partial a_j}{\partial W_{1j0}}) = \eta f_2'u \sum_{k=1}^{s_2}(e_kW_{2kj})f_1'
ΔW1j0=−ηk=1∑s2(∂ek∂E∂f2∂ek∂aj∂f2∂W1j0∂aj)=ηf2′uk=1∑s2(ekW2kj)f1′
表示为矩阵运算形式为
Δ
W
1
=
η
A
′
W
2
T
Y
′
e
u
T
\Delta W_1 = \eta \bm{A}'\bm{W}_2^T\bm{Y}'\bm{e} \bm{u}^T
ΔW1=ηA′W2TY′euT
其中,
A
′
=
d
i
a
g
[
f
1
j
′
]
s
1
×
s
1
\bm{A}'=diag[f_{1j}']_{s_1\times s_1}
A′=diag[f1j′]s1×s1,
Y
′
=
d
i
a
g
[
f
2
j
′
]
s
2
×
s
2
\bm{Y}'=diag[f_{2j}']_{s_2 \times s_2}
Y′=diag[f2j′]s2×s2为对角阵。
类似的,偏移量
b
1
b_1
b1的更新律只与权值
W
1
W_1
W1相差一个因子
u
u
u
Δ
b
1
j
=
η
f
2
′
f
1
′
∑
k
=
1
s
2
(
e
k
W
2
k
j
)
\Delta b_{1j} = \eta f_2'f_1' \sum_{k=1}^{s_2}(e_kW_{2kj})
Δb1j=ηf2′f1′k=1∑s2(ekW2kj)
化为矩阵运算形式为
Δ
b
1
=
η
A
′
W
2
T
Y
′
e
\Delta \bm{b}_1 = \eta \bm{A}'\bm{W}_2^T\bm{Y}'\bm{e}
Δb1=ηA′W2TY′e
BP神经网络拟合实例
采用BP神经网络对正弦函数 y = s i n ( t ) y=sin(t) y=sin(t)进行拟合。网络结构设置为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');
神经网络拟合结果如下