RBF神经网络介绍
RBF神经网络结构
径向基函数(Radial Basis Function, RBF)神经网络是一种单隐含层的三层前馈神经网络,网络结构如下图所示
RBF神经网络模拟了人脑中局部调整,相互覆盖接受域(或者说感受域,Receptive Field)的神经网络结构。与BP神经网络相同,研究人员已经证明RBF神经网络能够以任何精度逼近任意非线性函数。
RBF神经网络算法
便于分析,记RBF神经网络的输入为m维,隐含层有
s
1
s_1
s1个神经元,输出层有
s
2
s_2
s2个神经元。
RBF神经网络隐含层神经元的激活函数为如下所示的高斯基函数
h
j
=
exp
(
−
∣
∣
x
−
c
j
∣
∣
2
2
b
j
2
)
,
j
=
1
,
2
,
.
.
.
,
s
1
h_j = \exp(-\frac{||\bm{x}-\bm{c}_j||^2}{2b_j^2}),j=1,2,...,s_1
hj=exp(−2bj2∣∣x−cj∣∣2),j=1,2,...,s1
其中,
c
j
=
[
c
j
1
,
c
j
2
,
.
.
.
,
c
j
m
]
T
\bm{c}_j=[c_{j1},c_{j2},...,c_{jm}]^T
cj=[cj1,cj2,...,cjm]T为第j个隐含层神经元高斯基函数的中心向量,
m
m
m表示网络输入
x
\bm{x}
x的维数,
b
j
b_j
bj为第j个隐含层神经元高斯基函数的宽度。与之前提及的BP神经网络中的sigmod函数不同,高斯基函数只在有限的范围内,输入是非零的,超过一定的范围,其输出则为零。
在一维情况下,不同的
c
j
\bm{c}_j
cj和
b
j
b_j
bj对高斯基函数的影响如下图所示
可以看到,
b
j
b_j
bj越大,高斯基函数的非零输出区域越大,表明对输入的映射能力越强。
c
j
\bm{c_j}
cj表示非零输出区域的中心位置,输入离中心越近,其输出值会更大,表明高斯基函数对输入更加敏感。
RBF神经网络的输出为
y
=
W
H
\bm{y} = \bm{WH}
y=WH
其中,
W
∈
R
s
2
×
s
1
\bm{W}\in R^{s_2 \times {s_1}}
W∈Rs2×s1为RBF神经网络输出层权值矩阵,
H
∈
R
s
1
H \in R^{s_1}
H∈Rs1为隐含层输出,
H
=
[
h
1
,
h
2
,
.
.
.
,
h
s
1
]
T
\bm{H} = [h_1,h_2,...,h_{s_1}]^T
H=[h1,h2,...,hs1]T。
RBF神经网络逼近算法
相较BP神经网络,RBF神经网络结构更加简单,同时需要调节的参数也更少,只有输出层的权值矩阵
W
\bm{W}
W需要在训练过程中调节。与BP神经网络类似,我们可以以采用梯度下降法来调节权值矩阵。
定义RBF神经网络的估计误差指标为
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}|| \bm{y_d}-\bm{y}||^2
E=21i=1∑s2∣∣ei∣∣2=21i=1∑s2∣∣yd−y∣∣2
其中,
y
d
\bm{y_d}
yd为期望输出。
对误差指标关于输出层权值矩阵
W
\bm{W}
W中元素进行求导得到
∂
E
∂
W
i
0
=
∂
E
∂
e
i
∂
e
i
∂
y
i
∂
y
i
∂
W
i
0
=
−
e
i
h
i
\frac{\partial E}{\partial W_{i0}}=\frac{\partial E}{\partial e_i} \frac{\partial e_i}{\partial y_i} \frac{\partial y_i}{\partial W_{i0}}=-e_ih_i
∂Wi0∂E=∂ei∂E∂yi∂ei∂Wi0∂yi=−eihi
那么,权值可按如下方式调节
Δ
W
i
0
=
−
η
e
i
h
i
W
i
0
(
k
+
1
)
=
W
i
0
(
k
)
+
Δ
W
i
0
+
α
(
W
i
0
(
k
−
1
)
−
W
i
0
(
k
−
2
)
)
\Delta W_{i0} = -\eta e_ih_i \\ W_{i0}(k+1) = W_{i0}(k)+\Delta W_{i0} + \alpha (W_{i0}(k-1)-W_{i0}(k-2))
ΔWi0=−ηeihiWi0(k+1)=Wi0(k)+ΔWi0+α(Wi0(k−1)−Wi0(k−2))
其中,
η
∈
(
0
,
1
)
\eta\in(0,1)
η∈(0,1)为学习速度,
α
∈
(
0
,
1
)
\alpha \in(0,1)
α∈(0,1)为动量因子。
采用RBF神经网络逼近非线性函数
采用RBF神经网络,逼近简单的正弦函数
y
=
s
i
n
(
t
)
y=sin(t)
y=sin(t)
可知,采用的RBF神经网络输入和输出层神经元数量都为1,设置隐含层神经元数量为10个。
由于RBF神经网络采用的激活函数在有限区域内输出为非零,因此在设计RBF神经网络的时候,需要根据网络的输入来确定每个隐含层神经元激活函数的参数,即
c
j
c_j
cj和
b
j
b_j
bj。合适的网络参数能够提升网络的逼近效果和性能,而不合适的参数会导致神经网络训练失败,或者达不到想要的效果。
通常来说,
c
j
c_j
cj参数需要与网络的输入相匹配,要保证输入在高斯基函数的有效映射区域内;同样的,根据输入的范围和高斯基函数的中心,来设置一个合适的宽度参数
b
j
b_j
bj。
在本例中,神经网络的输入为时间
t
∈
[
0
,
10
]
t \in[0,10]
t∈[0,10],因此取径向基函数中心和宽度为
C
=
[
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
]
T
B
=
[
b
j
]
10
×
1
,
b
j
=
1
,
j
=
1
,
2
,
.
.
.
10
\bm{C} = [1,2,3,4,5,6,7,8,9,10] ^T \\ \bm{B} = [b_j]_{10\times 1},b_j = 1,j=1,2,...10
C=[1,2,3,4,5,6,7,8,9,10]TB=[bj]10×1,bj=1,j=1,2,...10
神经网络逼近结果
训练过程中误差收敛情况如下所示
将训练得到的神经网络进行验证
代码如下
%训练简单的RBF神经网络来拟合非线性函数
clear,clc
%% 生成训练数据
ts = 0.01;
u1 = 0;
y1 = 0;
for k=1:1000
u(k) = k*ts;
y(k) = sin(u(k));
end
len = length(u);
%% RBFNN初始设置
% RBFNN结构为1-10-1
n = 1;
s1 = 10;
s2 = 1;
c = (1:1:10); %高斯基函数中心
b = ones(s1,1).*2; %高斯基函数宽度
W = rand(s2,s1); %输出权值矩阵
DW = zeros(s2,s1);
Wt1 = zeros(s2,s1); %上一时刻权值阵
Wt2 = zeros(s2,s1); %上上时刻权值阵
H = zeros(s1,1); %隐含层输出
m = 500;
Error = zeros(m,s2);
%% 训练算法
e_tol = 1e-4;
irt_max = 20000;
e = ones(irt_max,1);
eta = 0.3;
alpha = 0.1;
for cnt = 1:irt_max
idx_rand = randperm(1000);
u_train = u(idx_rand);
y_train = y(idx_rand);
% 前向计算
for i = 1:m
x = u_train(i);
for j = 1:s1
H(j) = exp(-(x-c(j))^2/(2*b(j)^2)); %隐含层计算
end
y_etm = dot(W,H); %神经网络预测值
Error(i) = y_train(i) - y_etm;
% 权值更新
Wt = W; %当前时刻W
for j = 1:s1
DW(j) = eta*Error(i)*H(j);
W(j) = Wt(j) + DW(j) + alpha.*(Wt1(j)-Wt2(j)); %W update
end
Wt2 = Wt1;
Wt1 = Wt;
end
% 检测是否达到误差要求
e(cnt) = (norm(Error))^2/2/len;
if e(cnt) < e_tol
break;
end
end
检验训练结果
%% 检验训练结果
idx_vad = (1:20:1000);
u_test = u(idx_vad);
for i = 1:length(idx_vad)
x = u_test(i);
for j = 1:s1
H(j) = exp(-(x-c(j))^2/(2*b(j)^2)); %隐含层计算
end
y_test(i) = W*H; %神经网络预测值
end
figure(1)
plot(u,y,'b--','LineWidth',1);
hold on
plot(u_test,y_test,'r-*');
legend('reference','estimation')
grid on
figure(2)
plot(e(1:cnt));
grid on
legend('error')
%% 检验2
for i = 1:1000
u_test2(i) = i*ts*5;
y_test2(i) = sin(u_test2(i));
x = u_test2(i);
for j = 1:s1
H(j) = exp(-(x-c(j))^2/(2*b(j)^2)); %隐含层计算
end
y_vad2(i) = W*H;
end
figure(3)
plot(u_test2,y_vad2,'r','LineWidth',0.75);
hold on
plot(u_test2,y_test2,'b--','LineWidth',1)
grid on
legend('estimation','reference')