RBF神经网络简单介绍与MATLAB实现


RBF的直观介绍

RBF具体原理,网络上很多文章一定讲得比我好,所以我也不费口舌了,这里只说一说对RBF网络的一些直观的认识

1 RBF是一种两层的网络

是的,RBF结构上并不复杂,只有两层:隐层和输出层。其模型可以数学表示为:
y j = ∑ i = 1 n w i j ϕ ( ∥ x − u i ∥ 2 ) , ( j = 1 , … , p ) y_j = \sum_{i=1}^n w_{ij} \phi(\Vert x - u_i\Vert^2), (j = 1,\dots,p) yj=i=1nwijϕ(xui2),(j=1,,p)
在这里插入图片描述
在这里插入图片描述

2 RBF的隐层是一种非线性的映射

RBF隐层常用激活函数是高斯函数:
ϕ ( ∥ x − u ∥ ) = e − ∥ x − u ∥ 2 σ 2 \phi(\Vert x - u\Vert) = e^{-\frac{\Vert x-u\Vert^2}{\sigma^2}} ϕ(xu)=eσ2xu2

3 RBF输出层是线性的

4 RBF的基本思想是:将数据转化到高维空间,使其在高维空间线性可分

RBF隐层将数据转化到高维空间(一般是高维),认为存在某个高维空间能够使得数据在这个空间是线性可分的。因此啊,输出层是线性的。这和核方法的思想是一样一样的。下面举个老师PPT上的例子:
在这里插入图片描述

上面的例子,就将原来的数据,用高斯函数转换到了另一个二维空间中。在这个空间里,XOR问题得到解决。可以看到,转换的空间不一定是比原来高维的。

RBF学习算法

在这里插入图片描述

对于上图的RBF网络,其未知量有:中心向量 u i u_i ui,高斯函数中常数 σ \sigma σ,输出层权值 W W W
学习算法的整个流程大致如下图:
在这里插入图片描述

具体可以描述为:

  1. 利用kmeans算法寻找中心向量 u i u_i ui
  2. 利用kNN(K nearest neighbor)rule 计算 σ \sigma σ
    σ i = 1 K ∑ k = 1 K ∥ u k − u i ∥ 2 \sigma_i = \sqrt{\frac{1}{K}\sum_{k=1}^K \Vert u_k - u_i\Vert^2} σi=K1k=1Kukui2
  3. W W W可以利用最小二乘法求得

Lazy RBF

可以看到原来的RBF挺麻烦的,又是kmeans又是knn。后来就有人提出了lazy RBF,就是不用kmeans找中心向量了,将训练集的每一个数据都当成是中心向量。这样的话,核矩阵 Φ \Phi Φ就是一个方阵,并且只要保证训练中的数据是不同的,核矩阵 Φ \Phi Φ就是可逆的。这种方法确实lazy,缺点就是如果训练集很大,会导致核矩阵 Φ \Phi Φ也很大,并且要保证训练集个数要大于每个训练数据的维数。
在这里插入图片描述

MATLAB实现RBF神经网络

下面实现的RBF只有一个输出,供大家参考参考。对于多个输出,其实也很简单,就是 W W W变成了多个,这里就不实现了。

demo.m 对XOR数据进行了RBF的训练和预测,展现了整个流程。最后的几行代码是利用封装形式进行训练和预测。

clc;
clear all;
close all;

%% ---- Build a training set of a similar version of XOR
c_1 = [0 0];
c_2 = [1 1];
c_3 = [0 1];
c_4 = [1 0];

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 = [A;B];
data = X(:,1:2);
label = X(:,3);

%% Using kmeans to find cinter vector
n_center_vec = 10;
rng(1);
[idx, C] = 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
    [n, d] = 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
[W1, sigma1, C1] = RBF_training(data, label, 10);
y1 = RBF_predict(data, W, sigma, C1);
[W2, sigma2, C2] = lazyRBF_training(data, label, 2);
y2 = RBF_predict(data, W2, sigma2, C2);

在这里插入图片描述

上图是XOR训练集。其中蓝色的kmenas选取的中心向量。中心向量要取多少个呢?这也是玄学问题,总之不要太少就行,代码中取了10个,但是从结果 y y y来看,其实对于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);
    [idx, C] = 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
        [n] = 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的实现,主要就是中心向量为训练集自己,然后再构造核矩阵。由于 Φ \Phi Φ一定可逆,所以在求逆时,可以使用快速的’\‘方法

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

  • 86
    点赞
  • 670
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
您好!对于RBF(径向基函数)神经网络的粒子群优化(PSO)的Matlab程序,这里提供一个简单的示例代码供参考: ```matlab % RBF神经网络粒子群优化程序 % 数据准备 load('data.mat'); % 加载训练数据 X = data(:, 1:end-1); % 输入特征 Y = data(:, end); % 输出标签 % 定义RBF神经网络的参数 numCenters = 10; % RBF中心的数量 numInputs = size(X, 2); % 输入特征的数量 numOutputs = 1; % 输出标签的数量 % 定义PSO算法的参数 numParticles = 50; % 粒子数量 maxIterations = 100; % 最大迭代次数 = 0.5; % 惯性权重 c1 = 2; % 学习因子1(个体最优) c2 = 2; % 学习因子2(全局最优) % 初始化粒子位置和速度 particlePositions = rand(numCenters * numInputs + numOutputs, numParticles); particleVelocities = zeros(size(particlePositions)); % 初始化全局最优解和最优粒子位置 globalBestPosition = particlePositions(:, 1); globalBestFitness = inf; % 进行粒子群优化 for iter = 1:maxIterations % 计算每个粒子的适应度(使用均方误差作为适应度函数) particleFitness = zeros(numParticles, 1); for p = 1:numParticles % 更新RBF网络参数 centers = reshape(particlePositions(1:numCenters * numInputs, p), numCenters, numInputs); weights = particlePositions(numCenters * numInputs + 1:end, p); % 计算RBF网络的输出 outputs = zeros(size(Y)); for i = 1:size(X, 1) distances = sqrt(sum((X(i, :) - centers).^2, 2)); outputs(i) = sum(weights .* exp(-distances.^2)); end % 计算适应度 particleFitness(p) = mean((outputs - Y).^2); % 更新个体最优解和全局最优解 if particleFitness(p) < globalBestFitness globalBestFitness = particleFitness(p); globalBestPosition = particlePositions(:, p); end end % 更新粒子速度和位置 for p = 1:numParticles particleVelocities(:, p) = w * particleVelocities(:, p) + c1 * rand(size(particlePositions, 1), 1) .* (particlePositions(:, p) - particlePositions(:, p)) + c2 * rand(size(particlePositions, 1), 1) .* (globalBestPosition - particlePositions(:, p)); particlePositions(:, p) = particlePositions(:, p) + particleVelocities(:, p); end end % 输出最优的RBF网络参数 bestCenters = reshape(globalBestPosition(1:numCenters * numInputs), numCenters, numInputs); bestWeights = globalBestPosition(numCenters * numInputs + 1:end); disp('最优的RBF神经网络参数:'); disp('中心点:'); disp(bestCenters); disp('权重:'); disp(bestWeights); ``` 请注意,这只是一个简单的示例代码,仅用于说明RBF神经网络与粒子群优化的基本实现。实际应用中,您可能需要根据具体问题进行适当的调整和改进。希望对您有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值