RBF神经网络简单介绍与MATLAB实现
RBF的直观介绍RBF具体原理,网络上很多文章一定讲得比我好,所以我也不费口舌了,这里只说一说对RBF网络的一些直观的认识
1 RBF是一种两层的网络
是的,RBF结构上并不复杂,只有两层:隐层和输出层。其模型可以数学表示为:
yj=i=1∑nwijϕ(∥x−ui∥2),(j=1,…,p)
http://static.zybuluo.com/jiemojiemo/b3eoyjs7thelc0h5lnvxrd1j/image_1bhb7ve1n1k694ld13e7ml4dv69.png
http://static.zybuluo.com/jiemojiemo/nc21tvpbact73ggouxbfh596/image_1bhb883omc001gpb1sgr1pdo13gom.png
2 RBF的隐层是一种非线性的映射
RBF隐层常用激活函数是高斯函数:
ϕ(∥x−u∥)=e−σ2∥x−u∥2
3 RBF输出层是线性的
4 RBF的基本思想是:将数据转化到高维空间,使其在高维空间线性可分
RBF隐层将数据转化到高维空间(一般是高维),认为存在某个高维空间能够使得数据在这个空间是线性可分的。因此啊,输出层是线性的。这和核方法的思想是一样一样的。下面举个老师PPT上的例子:
http://static.zybuluo.com/jiemojiemo/taxrhx9p0u1rzpdxgornhetn/image_1bhb8jce7vfn1vernpf1g9a0e13.png
上面的例子,就将原来的数据,用高斯函数转换到了另一个二维空间中。在这个空间里,XOR问题得到解决。可以看到,转换的空间不一定是比原来高维的。
RBF学习算法
http://static.zybuluo.com/jiemojiemo/f260rrta51v700ntrvzf1iqn/image_1bhb8rkpfasorc61g01ch11m211g.png
对于上图的RBF网络,其未知量有:中心向量ui ,高斯函数中常数σ,输出层权值W。
学习算法的整个流程大致如下图:
<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
http://static.zybuluo.com/jiemojiemo/j9fk80huomswlg916u8p20mm/image_1bhb91mfg14nmve8amcji21vkf1t.png
具体可以描述为:
1.利用kmeans算法寻找中心向量 ui
2.利用kNN(K nearest neighbor)rule 计算 σ
σ
i=K1k=1∑K∥uk−ui∥2
3. W 可以利用最小二乘法求得
Lazy RBF
可以看到原来的RBF挺麻烦的,又是kmeans又是knn。后来就有人提出了lazy RBF,就是不用kmeans找中心向量了,将训练集的每一个数据都当成是中心向量。这样的话,核矩阵Φ就是一个方阵,并且只要保证训练中的数据是不同的,核矩阵Φ就是可逆的。这种方法确实lazy,缺点就是如果训练集很大,会导致核矩阵Φ也很大,并且要保证训练集个数要大于每个训练数据的维数。
http://static.zybuluo.com/jiemojiemo/epzl1au1s0nyidvbq5ncjhyh/image_1bhba9lrnh8f1n2o5pt1pmksv92a.png
MATLAB实现RBF神经网络下面实现的RBF只有一个输出,供大家参考参考。对于多个输出,其实也很简单,就是WWW变成了多个,这里就不实现了。
demo.m 对XOR数据进行了RBF的训练和预测,展现了整个流程。最后的几行代码是利用封装形式进行训练和预测。
clc;
clear all;
close all;
%% ---- Build a training set of a similar version of XOR
c_1 = ;
c_2 = ;
c_3 = ;
c_4 = ;
n_L1 = 20; % number of label 1
n_L2 = 20; % number of label 2
A = zeros(n_L1*2, 3);
A(:,3) = 1;
B = zeros(n_L2*2, 3);
B(:,3) = 0;
% create random points
for i=1:n_L1
A(i, 1:2) = c_1 + rand(1,2)/2;
A(i+n_L1, 1:2) = c_2 + rand(1,2)/2;
end
for i=1:n_L2
B(i, 1:2) = c_3 + rand(1,2)/2;
B(i+n_L2, 1:2) = c_4 + rand(1,2)/2;
end
% show points
scatter(A(:,1), A(:,2),[],'r');
hold on
scatter(B(:,1), B(:,2),[],'g');
X = ;
data = X(:,1:2);
label = X(:,3);
%% Using kmeans to find cinter vector
n_center_vec = 10;
rng(1);
= kmeans(data, n_center_vec);
hold on
scatter(C(:,1), C(:,2), 'b', 'LineWidth', 2);
%% Calulate sigma
n_data = size(X,1);
% calculate K
K = zeros(n_center_vec, 1);
for i=1:n_center_vec
K(i) = numel(find(idx == i));
end
% Using knnsearch to find K nearest neighbor points for each center vector
% then calucate sigma
sigma = zeros(n_center_vec, 1);
for i=1:n_center_vec
= knnsearch(data, C(i,:), 'k', K(i));
L2 = (bsxfun(@minus, data(n,:), C(i,:)).^2);
L2 = sum(L2(:));
sigma(i) = sqrt(1/K(i)*L2);
end
%% Calutate weights
% kernel matrix
k_mat = zeros(n_data, n_center_vec);
for i=1:n_center_vec
r = bsxfun(@minus, data, C(i,:)).^2;
r = sum(r,2);
k_mat(:,i) = exp((-r.^2)/(2*sigma(i)^2));
end
W = pinv(k_mat'*k_mat)*k_mat'*label;
y = k_mat*W;
%y(y>=0.5) = 1;
%y(y<0.5) = 0;
%% training function and predict function
= RBF_training(data, label, 10);
y1 = RBF_predict(data, W, sigma, C1);
= lazyRBF_training(data, label, 2);
y2 = RBF_predict(data, W2, sigma2, C2);
http://static.zybuluo.com/jiemojiemo/7gwr6gkjn0xg7agfzwicm2yu/image_1bhbap6djuvg9uu1trs145d1f3b2n.png
上图是XOR训练集。其中蓝色的kmenas选取的中心向量。中心向量要取多少个呢?这也是玄学问题,总之不要太少就行,代码中取了10个,但是从结果yyy来看,其实对于XOR问题来说,4个就可以了。
RBF_training.m 对demo.m中训练的过程进行封装
function [ W, sigma, C ] = RBF_training( data, label, n_center_vec )
%RBF_TRAINING Summary of this function goes here
% Detailed explanation goes here
% Using kmeans to find cinter vector
rng(1);
= kmeans(data, n_center_vec);
% Calulate sigma
n_data = size(data,1);
% calculate K
K = zeros(n_center_vec, 1);
for i=1:n_center_vec
K(i) = numel(find(idx == i));
end
% Using knnsearch to find K nearest neighbor points for each center vector
% then calucate sigma
sigma = zeros(n_center_vec, 1);
for i=1:n_center_vec
= knnsearch(data, C(i,:), 'k', K(i));
L2 = (bsxfun(@minus, data(n,:), C(i,:)).^2);
L2 = sum(L2(:));
sigma(i) = sqrt(1/K(i)*L2);
end
% Calutate weights
% kernel matrix
k_mat = zeros(n_data, n_center_vec);
for i=1:n_center_vec
r = bsxfun(@minus, data, C(i,:)).^2;
r = sum(r,2);
k_mat(:,i) = exp((-r.^2)/(2*sigma(i)^2));
end
W = pinv(k_mat'*k_mat)*k_mat'*label;
end
RBF_lazytraning.m 对lazy RBF的实现,主要就是中心向量为训练集自己,然后再构造核矩阵。由于Φ一定可逆,所以在求逆时,可以使用快速的'/'方法
function [ W, sigma, C ] = lazyRBF_training( data, label, sigma )
%LAZERBF_TRAINING Summary of this function goes here
% Detailed explanation goes here
if nargin < 3
sigma = 1;
end
n_data = size(data,1);
C = data;
% make kernel matrix
k_mat = zeros(n_data);
for i=1:n_data
L2 = sum((data - repmat(data(i,:), n_data, 1)).^2, 2);
k_mat(i,:) = exp(L2'/(2*sigma));
end
W = k_mat\label;
end
RBF_predict.m 预测
function [ y ] = RBF_predict( data, W, sigma, C )
%RBF_PREDICT Summary of this function goes here
% Detailed explanation goes here
n_data = size(data, 1);
n_center_vec = size(C, 1);
if numel(sigma) == 1
sigma = repmat(sigma, n_center_vec, 1);
end
% kernel matrix
k_mat = zeros(n_data, n_center_vec);
for i=1:n_center_vec
r = bsxfun(@minus, data, C(i,:)).^2;
r = sum(r,2);
k_mat(:,i) = exp((-r.^2)/(2*sigma(i)^2));
end
y = k_mat*W;
end
————————————————
版权声明:本文为CSDN博主「芥末的无奈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weiwei9363/article/details/72808496
页:
[1]