【RBF預(yù)測】基于混沌時間序列改進(jìn)RBF神經(jīng)網(wǎng)絡(luò)實現(xiàn)預(yù)測matlab源碼
RBF的直觀介紹
RBF具體原理,網(wǎng)絡(luò)上很多文章一定講得比我好,所以我也不費(fèi)口舌了,這里只說一說對RBF網(wǎng)絡(luò)的一些直觀的認(rèn)識
1 RBF是一種兩層的網(wǎng)絡(luò)
是的,RBF結(jié)構(gòu)上并不復(fù)雜,只有兩層:隱層和輸出層。其模型可以數(shù)學(xué)表示為:
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=1∑nwij?(∥x?ui∥2),(j=1,…,p)


2 RBF的隱層是一種非線性的映射
RBF隱層常用激活函數(shù)是高斯函數(shù):
? ( ∥ x ? u ∥ ) = e ? ∥ x ? u ∥ 2 σ 2 \phi(\Vert x - u\Vert) = e^{-\frac{\Vert x-u\Vert^2}{\sigma^2}}?(∥x?u∥)=e?σ2∥x?u∥2
3 RBF輸出層是線性的
4 RBF的基本思想是:將數(shù)據(jù)轉(zhuǎn)化到高維空間,使其在高維空間線性可分
RBF隱層將數(shù)據(jù)轉(zhuǎn)化到高維空間(一般是高維),認(rèn)為存在某個高維空間能夠使得數(shù)據(jù)在這個空間是線性可分的。因此啊,輸出層是線性的。這和核方法的思想是一樣一樣的。下面舉個老師PPT上的例子:

上面的例子,就將原來的數(shù)據(jù),用高斯函數(shù)轉(zhuǎn)換到了另一個二維空間中。在這個空間里,XOR問題得到解決??梢钥吹剑D(zhuǎn)換的空間不一定是比原來高維的。
RBF學(xué)習(xí)算法

對于上圖的RBF網(wǎng)絡(luò),其未知量有:中心向量u i u_iui,高斯函數(shù)中常數(shù)σ \sigmaσ,輸出層權(quán)值W WW。
學(xué)習(xí)算法的整個流程大致如下圖:

具體可以描述為:
利用kmeans算法尋找中心向量u i u_iui
利用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=1∑K∥uk?ui∥2W WW可以利用最小二乘法求得
Lazy RBF
可以看到原來的RBF挺麻煩的,又是kmeans又是knn。后來就有人提出了lazy RBF,就是不用kmeans找中心向量了,將訓(xùn)練集的每一個數(shù)據(jù)都當(dāng)成是中心向量。這樣的話,核矩陣Φ \PhiΦ就是一個方陣,并且只要保證訓(xùn)練中的數(shù)據(jù)是不同的,核矩陣Φ \PhiΦ就是可逆的。這種方法確實lazy,缺點(diǎn)就是如果訓(xùn)練集很大,會導(dǎo)致核矩陣Φ \PhiΦ也很大,并且要保證訓(xùn)練集個數(shù)要大于每個訓(xùn)練數(shù)據(jù)的維數(shù)。

MATLAB實現(xiàn)RBF神經(jīng)網(wǎng)絡(luò)
下面實現(xiàn)的RBF只有一個輸出,供大家參考參考。對于多個輸出,其實也很簡單,就是W WW變成了多個,這里就不實現(xiàn)了。
demo.m 對XOR數(shù)據(jù)進(jìn)行了RBF的訓(xùn)練和預(yù)測,展現(xiàn)了整個流程。最后的幾行代碼是利用封裝形式進(jìn)行訓(xùn)練和預(yù)測。
% 混沌時間序列的 rbf 預(yù)測(一步預(yù)測) -- 主函數(shù)
clc
clear all
close all
%--------------------------------------------------------------------------
% 產(chǎn)生混沌序列
% dx/dt = sigma*(y-x)
% dy/dt = r*x - y - x*z
% dz/dt = -b*z + x*y
sigma = 16; ? ? ? ? ? ? % Lorenz 方程參數(shù) a
b = 4; ? ? ? ? ? ? ? ? ?% ? ? ? ? ? ? ? ? b
r = 45.92; ? ? ? ? ? ? ?% ? ? ? ? ? ? ? ? c ? ? ? ? ? ?
y = [-1,0,1]; ? ? ? ? ? % 起始點(diǎn) (1 x 3 的行向量)
h = 0.01; ? ? ? ? ? ? ? % 積分時間步長
k1 = 30000; ? ? ? ? ? ? % 前面的迭代點(diǎn)數(shù)
k2 = 5000; ? ? ? ? ? ? ?% 后面的迭代點(diǎn)數(shù)
Z = LorenzData(y,h,k1+k2,sigma,r,b);
X = Z(k1+1:end,1); ? ? ?% 時間序列
X = normalize_a(X,1); ? % 信號歸一化到均值為0,振幅為1
%--------------------------------------------------------------------------
% 相關(guān)參數(shù)
t = 1; ? ? ? ? ? ? ? ? ?% 時延
d = 3; ? ? ? ? ? ? ? ? ?% 嵌入維數(shù)
n_tr = 1000; ? ? ? ? ? ?% 訓(xùn)練樣本數(shù)
n_te = 1000; ? ? ? ? ? ?% 測試樣本數(shù)
%--------------------------------------------------------------------------
% 相空間重構(gòu)
X_TR = X(1:n_tr);
X_TE = X(n_tr+1:n_tr+n_te);
figure,plot(1:1:n_tr,X_TR,'r');
hold on
plot(n_tr+1:1:n_tr+n_te,X_TE,'b');
hold off
[XN_TR,DN_TR] = PhaSpaRecon(X_TR,t,d);
[XN_TE,DN_TE] = PhaSpaRecon(X_TE,t,d);
%--------------------------------------------------------------------------
% 訓(xùn)練與測試
P = XN_TR;
T = DN_TR;
spread = 1; ? ? ? % 此值越大,覆蓋的函數(shù)值就大(默認(rèn)為1)
net = newrbe(P,T,spread);
ERR1 = sim(net,XN_TR)-DN_TR;
err_mse1 = mean(ERR1.^2);
perr1 = err_mse1/var(X)
DN_PR = sim(net,XN_TE);
ERR2 = DN_PR-DN_TE;
err_mse2 = mean(ERR2.^2);
perr2 = err_mse2/var(X)
%--------------------------------------------------------------------------
% 結(jié)果做圖
figure;
subplot(211);
plot(1:length(ERR2),DN_TE,'r+-',1:length(ERR2),DN_PR,'b-');
title('真實值(+)與預(yù)測值(.)')
subplot(212);
plot(ERR2,'k');
title('預(yù)測絕對誤差')



?