数学建模社区-数学中国
标题:
RBF神经网络简单介绍与MATLAB实现
[打印本页]
作者:
zhangtt123
时间:
2020-5-23 14:56
标题:
RBF神经网络简单介绍与MATLAB实现
RBF的直观介绍
) z( N; N# d0 T7 m4 \
RBF具体原理,网络上很多文章一定讲得比我好,所以我也不费口舌了,这里只说一说对RBF网络的一些直观的认识
$ d2 F8 R7 @) |) F+ o, U7 w1 h4 i0 C
; R4 H7 T" a' A( M. c) }
1 RBF是一种两层的网络
# S" }, w0 o. Q- T
是的,RBF结构上并不复杂,只有两层:隐层和输出层。其模型可以数学表示为:
9 g& t3 t' z7 h9 C( U
yj=
i=1∑nwijϕ(∥x−
ui∥2),(j=
1,…,p)
0 `3 T/ i8 I! G9 V6 R" s
4 z, W, e1 L# k4 |
" `, D3 Q. C) ~, K
2 RBF的隐层是一种非线性的映射
& l9 P- O. @ S2 }
RBF隐层常用激活函数是高斯函数:
% }6 y4 Z6 ~0 D$ d: \0 Q j6 V" B
2 E; t) \. B* i1 `; X5 H6 x: Y( W& {4 }
ϕ(∥x−
u∥)=
e−σ2∥x−u∥2
/ Y( v# Y, t& J* `; ]
" n: O. ]+ P8 s
3 U( M' [5 p0 r' _/ G0 L
& |! x7 }' a5 f; ]7 a: L
3 RBF输出层是线性的
_5 U i# @! Z0 e8 M( \" { u; S
4 RBF的基本思想是:将数据转化到高维空间,使其在高维空间线性可分
4 o; C* V& z; k& O; Q2 ~
RBF隐层将数据转化到高维空间(一般是高维),认为存在某个高维空间能够使得数据在这个空间是线性可分的。因此啊,输出层是线性的。这和核方法的思想是一样一样的。下面举个老师PPT上的例子:
7 ~: V9 @0 t' D+ ]; `* U
# y" f% Z9 Z+ {7 H3 h1 X/ V
, `; W( p, o9 E- `
上面的例子,就将原来的数据,用高斯函数转换到了另一个二维空间中。在这个空间里,XOR问题得到解决。可以看到,转换的空间不一定是比原来高维的。
& `9 r- C5 I9 ^7 L. i
7 V, _0 }# Y9 x2 T! J
RBF学习算法
' I6 Q, p. ^; i6 m6 ^9 T1 G Z
. U, e8 d. f3 B) I9 W9 A1 R9 N: H
2 I: T/ P5 e8 J, W0 `" D1 {
. D! \. U! n" H5 j- r7 H
对于上图的RBF网络,其未知量有:
中心向量
ui
,
高斯函数中常数σ,
输出层权值
W。
' S+ J3 E6 @6 }- }3 l+ J* |
学习算法的整个流程大致如下图:
3 g4 d; l" z# l* e
<span class="MathJax" id="MathJax-Element-5-Frame" tabindex="0" data-mathml="W W" role="presentation" style="box-sizing: border-box; outline: 0px; display: inline; line-height: normal; font-size: 19.36px; word-spacing: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; position: relative;">WW
9 ^7 v! m1 g" q8 H r
4 R0 l8 \" |4 a$ {- ]
) {8 p* @+ c* d3 Z# M: d* P
具体可以描述为:
( |- O/ c% W5 h/ v6 _8 _% o
, q6 J! J' E5 y: E& R
1.利用kmeans算法寻找中心向量
[color=rgba(0, 0, 0, 0.749019607843137)]
ui
% i, b6 ?/ }- Y( M" T* u3 ^
& u0 A. z" ]2 Z# k2 i9 ^
2.利用kNN(K nearest neighbor)rule 计算 σ[color=rgba(0, 0, 0, 0.75)]
- h; X0 q, Y1 k4 n: A. j _
σ
$ g* h% B; e; @9 b5 \- a' {
i=
K1k=1∑K∥uk−ui∥2
$ _. s7 k7 i% _
" t3 V Y; z* f' b4 F
& L# L4 H0 S' Y. X+ J5 H; Q
' A. ]; v' i5 I
3. [color=rgba(0, 0, 0, 0.75)]
W
[color=rgba(0, 0, 0, 0.75)]
可以利用最小二乘法求得
: V, S2 P* A/ g0 s' e
- f2 Y7 H! g3 }$ I$ g
Lazy RBF
/ N* @# G8 I' c# n1 A
# v$ C) Z8 ~5 v- i! V
可以看到原来的RBF挺麻烦的,又是kmeans又是knn。后来就有人提出了lazy RBF,就是不用kmeans找中心向量了,将训练集的每一个数据都当成是中心向量。这样的话,核矩阵Φ就是一个方阵,并且只要保证训练中的数据是不同的,核矩阵Φ就是可逆的。这种方法确实lazy,缺点就是如果训练集很大,会导致核矩阵Φ也很大,并且要保证训练集个数要大于每个训练数据的维数。
8 V, C2 e" K8 g: d8 H
5 O' S8 Q0 ]3 j8 U7 S
MATLAB实现RBF神经网络
下面实现的RBF只有一个输出,供大家参考参考。对于多个输出,其实也很简单,就是WWW变成了多个,这里就不实现了。
8 S; Y. E4 S9 Z' k) h: l ?
& }# e- v2 g& a8 S) `5 G% q
demo.m 对XOR数据进行了RBF的训练和预测,展现了整个流程。最后的几行代码是利用封装形式进行训练和预测。
: \$ Y/ S) I6 L |6 z& _( \- H9 b
* p+ d* u3 b# E3 |% l/ J
clc;
2 u7 |: c# r2 V" ^6 o1 X
clear all;
0 t6 y) K ]2 j; t
close all;
6 m9 D% _5 f6 P- R' `$ I. m' ~
0 K- X/ l) u+ K
%% ---- Build a training set of a similar version of XOR
" o8 e; T4 D9 d( H5 \$ X
c_1 = [0 0];
% t8 [9 c2 j! e8 k
c_2 = [1 1];
, E7 K- f6 k4 ]
c_3 = [0 1];
- n; Z! O W, U- o( a3 M G
c_4 = [1 0];
/ q- b4 m" B/ A0 o4 ?+ X u
/ R0 x* \: Z( g V9 d3 ?8 p& n
n_L1 = 20; % number of label 1
3 d- [5 I5 ~0 D! _- g' l
n_L2 = 20; % number of label 2
4 b5 H; L& q) K* }' y; O$ ?/ k
0 L4 Q5 h5 x% {# s" \
m+ R8 e' B8 I6 ^
A = zeros(n_L1*2, 3);
8 S1 N/ d2 {. K2 z
A(:,3) = 1;
* O! e9 d, c" E0 x( t; d
B = zeros(n_L2*2, 3);
. ^5 o2 e7 V$ C( O
B(:,3) = 0;
! l9 a! C8 M, D1 R+ f
. t) ^) U+ z; F
% create random points
; h/ [/ R" m& H; L2 w* `
for i=1:n_L1
; U: `, m5 C* ?0 i
A(i, 1:2) = c_1 + rand(1,2)/2;
: F4 g' I! H6 i1 n8 V: V2 I
A(i+n_L1, 1:2) = c_2 + rand(1,2)/2;
0 Q2 S3 L; I3 @( A2 w2 m. l
end
! z" z' t% k& Q9 ?3 b6 _8 h# o
for i=1:n_L2
! W5 t; ]% Z: i9 q: I
B(i, 1:2) = c_3 + rand(1,2)/2;
' j4 x% h h+ t. q. [' G* @( P
B(i+n_L2, 1:2) = c_4 + rand(1,2)/2;
7 N. {- b+ \- H0 @9 }3 M
end
( H- u9 E% B$ J( N( J
8 E" T* D- p" w, V$ \5 A
% show points
# T: C/ ^- Z) k/ {5 s" \6 Q3 W
scatter(A(:,1), A(:,2),[],'r');
6 C8 `" s# \! g
hold on
* I( n, l% l3 p" n
scatter(B(:,1), B(:,2),[],'g');
( Q0 g9 o2 A5 J" K) \; q5 e# w
X = [A;B];
" F P& j3 P1 I$ X' ]" Z
data = X(:,1:2);
3 e2 Y3 F; f6 L% ~- V
label = X(:,3);
4 z; v6 g5 Q: d4 ` Y
: K- G& j. M( N& {& |
%% Using kmeans to find cinter vector
; X6 d3 P9 {# ^2 n5 `( Z, B
n_center_vec = 10;
4 e3 `2 N- T( r: n5 ~6 M y
rng(1);
0 `9 q" P( Z- S! p: m- m% G
[idx, C] = kmeans(data, n_center_vec);
3 x9 c E( I" W6 D1 [% d1 t7 Y
hold on
' V6 ?- P' e9 k9 |6 u i5 R% r
scatter(C(:,1), C(:,2), 'b', 'LineWidth', 2);
; ~8 A% s# e8 S+ B7 v
. C' @; |+ F) y' p5 T( K+ k4 J
%% Calulate sigma
+ @# F! Q- V _& ?
n_data = size(X,1);
: w" m. l. ?4 X6 [8 `, m
?& l8 p! N2 h& z
% calculate K
: ~% K8 D, f6 C" J$ R& \, I
K = zeros(n_center_vec, 1);
' ~9 R1 J: t) [5 ^
for i=1:n_center_vec
/ f% m8 J& X/ ~5 T4 C u7 _1 `
K(i) = numel(find(idx == i));
6 w8 `" ?3 F l1 K6 G! c8 V: ^3 P
end
5 \5 a# M6 q! L0 G5 v$ u0 O7 i6 f
+ I/ L4 p& K) Y! A0 a. j, t& m7 ?
% Using knnsearch to find K nearest neighbor points for each center vector
/ P9 G2 p3 e* r7 U
% then calucate sigma
# G* _1 U# M7 a7 \
sigma = zeros(n_center_vec, 1);
% y" D% A. S4 s
for i=1:n_center_vec
~" S" F; |; n# I* N4 E
[n, d] = knnsearch(data, C(i,:), 'k', K(i));
; S# \+ N5 W/ ^3 o
L2 = (bsxfun(@minus, data(n,:), C(i,:)).^2);
+ ?8 O: H: c- G0 G
L2 = sum(L2(:));
: J `5 G3 j& m- p" B
sigma(i) = sqrt(1/K(i)*L2);
( u5 T7 N5 j) z. G4 s+ O
end
, e7 _+ a, [7 |9 N- Q- n3 N# ]
1 A+ q" k1 r, U4 n; {
%% Calutate weights
# ^& ] X5 H+ _" i
% kernel matrix
% E( Z0 J v! q& B& ^" r/ y- s& \
k_mat = zeros(n_data, n_center_vec);
2 t. |1 |1 V W, M* p# ]
# b2 d5 x7 J% A2 f% g
for i=1:n_center_vec
( [( k! @3 ^1 t! d8 v8 D. W, F
r = bsxfun(@minus, data, C(i,:)).^2;
9 Y& N" @; @3 P8 \& Q
r = sum(r,2);
' I& h E' D8 T
k_mat(:,i) = exp((-r.^2)/(2*sigma(i)^2));
( V& N [2 I) K0 A4 m
end
u% E" x2 N- r% D2 ?9 b
8 I3 i1 r7 [ s) ?4 h) l( Z" l
W = pinv(k_mat'*k_mat)*k_mat'*label;
% j% u7 V* P4 U7 r: G N% v( N- ~
y = k_mat*W;
6 Q, {" P0 h: L3 e% q! L
%y(y>=0.5) = 1;
% Z$ [& I# e) e
%y(y<0.5) = 0;
1 X2 M1 P( a' G$ t4 [ {
, i! ~! p/ H0 p" ~1 O# u
%% training function and predict function
* i$ T: t |- N* c! d* B. {
[W1, sigma1, C1] = RBF_training(data, label, 10);
: ?. T, b7 [$ z& P/ `' c. x8 K, s
y1 = RBF_predict(data, W, sigma, C1);
( `8 O4 y% I0 b8 E5 y* L
[W2, sigma2, C2] = lazyRBF_training(data, label, 2);
: `: Q% W/ G& _0 G+ d9 z
y2 = RBF_predict(data, W2, sigma2, C2);
/ v0 c7 z9 ?8 @. ?9 J
- s( V$ @, b0 A6 D; @4 n
0 o( |, ~, M6 a$ a6 C
上图是XOR训练集。其中蓝色的kmenas选取的中心向量。中心向量要取多少个呢?这也是玄学问题,总之不要太少就行,代码中取了10个,但是从结果yyy来看,其实对于XOR问题来说,4个就可以了。
. J' p! M$ V3 v& i- m
8 P9 X$ v% @) A5 n0 X2 |
RBF_training.m 对demo.m中训练的过程进行封装
: F: h( _1 f8 {- T' l
function [ W, sigma, C ] = RBF_training( data, label, n_center_vec )
* |# G4 r4 q: \& x
%RBF_TRAINING Summary of this function goes here
I$ H* ?8 d5 ?1 Q3 h# t
% Detailed explanation goes here
" e; k# }! d$ [
) z4 J2 {4 d+ b6 \
% Using kmeans to find cinter vector
' Q! D) M9 h: u. I, ], o
rng(1);
! T' i e8 A7 w! Y: V* a: H6 v3 q
[idx, C] = kmeans(data, n_center_vec);
% O W( a1 N$ U# U
9 k9 b- g* S5 I; y; p3 C. I' |8 h* [
% Calulate sigma
9 O) q; `3 e# ~/ ] N9 p
n_data = size(data,1);
7 B3 t5 v; b( ~. k D: v
+ J% R+ v& X, x. K) Q+ C6 Y# U
% calculate K
# f7 h; `3 m1 s" Z. f6 o
K = zeros(n_center_vec, 1);
, X9 K3 h3 J1 o U) |3 F: T2 W
for i=1:n_center_vec
7 {8 m# A6 Y% X! e/ J
K(i) = numel(find(idx == i));
- T) v: Y9 W2 u' A; B& n
end
5 K) h9 P- D2 b0 y% A# K/ K$ w d
( J# Q8 G) a; ^6 U! a Q+ m( Y
% Using knnsearch to find K nearest neighbor points for each center vector
& U/ v; b/ }* }, N
% then calucate sigma
2 ?1 ?8 m% A+ [, `1 q! O; u8 {% r
sigma = zeros(n_center_vec, 1);
# b% Q* q. s- S* y$ ]8 A6 a
for i=1:n_center_vec
& N6 V& d0 g' ^4 J
[n] = knnsearch(data, C(i,:), 'k', K(i));
5 ?9 D$ T+ b9 ^* ~$ {# }
L2 = (bsxfun(@minus, data(n,:), C(i,:)).^2);
1 z6 m/ U& R1 \) c
L2 = sum(L2(:));
" |7 X/ f& q& f; w
sigma(i) = sqrt(1/K(i)*L2);
5 e" o8 u* C$ h
end
, y0 a! V8 D) V$ b2 F: N8 s; p
% Calutate weights
6 N6 G/ V3 J1 P1 Q$ |. C1 z
% kernel matrix
* J1 M V' x }! Q, [" H
k_mat = zeros(n_data, n_center_vec);
3 D2 H2 j4 D) W6 _0 W
9 K! X0 ^% ~: a1 A$ m4 K
for i=1:n_center_vec
' _' e( q8 ]$ I$ ?. J8 ` W
r = bsxfun(@minus, data, C(i,:)).^2;
- H U3 a m2 G
r = sum(r,2);
$ {% q9 G! M# \' {/ ^% y) A- Y
k_mat(:,i) = exp((-r.^2)/(2*sigma(i)^2));
9 t" `0 L3 r0 J& R9 f+ R7 B
end
) S, d; B! J D' g! W' n3 i
6 R$ I0 U' @( b+ ^. u
W = pinv(k_mat'*k_mat)*k_mat'*label;
4 E9 m% S0 H# S/ u6 _$ N
end
1 D( d A7 x- ~( \2 I6 c* B9 O$ S
% _8 T2 I2 d. Z0 r
RBF_lazytraning.m 对lazy RBF的实现,主要就是中心向量为训练集自己,然后再构造核矩阵。由于Φ一定可逆,所以在求逆时,可以使用快速的'/'方法
9 e. O1 N3 d5 w. g2 [! [" U# L. j
) l& v& z; W4 ]5 m0 H
function [ W, sigma, C ] = lazyRBF_training( data, label, sigma )
9 e8 A/ G/ m$ Z+ i' a) D6 p
%LAZERBF_TRAINING Summary of this function goes here
7 D' G7 |; N9 D( ^' M8 T
% Detailed explanation goes here
$ V R: `$ _! e$ d
if nargin < 3
2 j3 F2 t+ o+ g
sigma = 1;
7 A2 g8 z" m: v
end
) }9 s4 ~ n# {% D/ P, d4 ?) n
5 _3 a3 H* [1 S! M( i- T$ ^
n_data = size(data,1);
' k+ Y, k# w" w/ t9 x: C
C = data;
; W6 r, s- |. I# e3 d" w
' F* I9 ~3 q( O$ R" d& o
% make kernel matrix
3 `) G$ @& s. r# ?" _) Q$ ^
k_mat = zeros(n_data);
6 @" \" ^& @5 E- {
for i=1:n_data
; }* R9 u! {5 M
L2 = sum((data - repmat(data(i,:), n_data, 1)).^2, 2);
# ^3 s, |; F/ y+ r' I
k_mat(i,:) = exp(L2'/(2*sigma));
) D, m3 |3 [+ s) O. H% j
end
7 x; ?9 q" n5 M* i( ?- K
9 t6 Z; } Y' M) S& p& w
W = k_mat\label;
0 L7 Y3 b z' v. }8 u' e# w D
end
3 U2 C3 g8 v3 U2 H
# Y: V9 I# e) r
RBF_predict.m 预测
) P5 o2 n: j6 k# [7 ~- M
9 c1 {0 ^( X- w& R% p1 N
function [ y ] = RBF_predict( data, W, sigma, C )
& R" b; E9 r. r: J/ }2 ]) J7 f
%RBF_PREDICT Summary of this function goes here
& ^# x0 ]/ T8 }9 r! m) j u3 Q L7 J I
% Detailed explanation goes here
5 l: w# k2 W* ^7 u( f8 V
n_data = size(data, 1);
0 [/ t1 X4 g3 W- B" \
n_center_vec = size(C, 1);
* i4 D" @% }" x B7 o
if numel(sigma) == 1
. I! c0 v- E, v8 @5 Y$ T
sigma = repmat(sigma, n_center_vec, 1);
, V$ ]7 e- Q& z& W$ ~# I5 F
end
) p4 D e2 n" W1 q% Z$ X8 O- y
- [6 [+ N7 n9 S" c
% kernel matrix
/ X5 j5 K n5 B$ a5 o0 ?- D5 K
k_mat = zeros(n_data, n_center_vec);
1 [% k/ X1 m+ E6 `0 k
for i=1:n_center_vec
5 ?1 N! e( M/ \9 w" o; J
r = bsxfun(@minus, data, C(i,:)).^2;
2 `) C: S S- b
r = sum(r,2);
! i6 ^! \5 j( k7 n, @
k_mat(:,i) = exp((-r.^2)/(2*sigma(i)^2));
. c& A! u' x# E& R
end
{- K0 b6 V- X2 E
: u$ N" t# _8 R7 [0 c! H5 E
y = k_mat*W;
1 q; J# f! R" }) i& f- ~1 O' f2 i
end
8 C% U3 n0 W& N- z4 L
$ d) v. D) X9 U3 \. u; ?
————————————————
* Q* p3 k& \4 v" s2 l) n, Y
版权声明:本文为CSDN博主「芥末的无奈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
6 M, e/ O- x5 e7 n: B
原文链接:https://blog.csdn.net/weiwei9363/article/details/72808496
; {- [: p3 t$ m. k T
! N. Z6 `3 h! F/ e% u& Z5 f/ Z3 r$ q
( |3 r8 X( i p
3 @5 k' u& T- d/ q/ m
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5