【Matlab學習手記】BP神經網絡數據滾動預測

BP神經網絡滾動預測未來數據:將預測的下一年數據作爲已知數據繼續預測下一年。

  • 代碼
clear; clc;
data = [0         0.0252    0.0550    0.1104    0.1480
        0.0252    0.0550    0.1104    0.1480    0.2111
        0.0550    0.1104    0.1480    0.2111    0.3369
        0.1104    0.1480    0.2111    0.3369    0.5482
        0.1480    0.2111    0.3369    0.5482    0.6612
        0.2111    0.3369    0.5482    0.6612    0.7127
        0.3369    0.5482    0.6612    0.7127    0.7598
        0.5482    0.6612    0.7127    0.7598    0.7720
        0.6612    0.7127    0.7598    0.7720    0.8274
        0.7127    0.7598    0.7720    0.8274    1.0000];
minValue = 320.9;
maxValue = 8338;
[rowLen, colLen] = size(data);
TestSamNum = rowLen;    % 訓練樣本數量
HiddenUnitNum = 9;      % 隱含層
InDim = colLen - 1;     % 輸入層
OutDim = 1;             % 輸出層
p = data(:, 1:InDim)';  % 輸入數據矩陣
t = data(:, colLen)';   % 目標數據矩陣
% [SamIn, minP, maxP, tn, minT, maxT] = premnmx(p, t);   % 原始樣本對(輸入和輸出)初始化
[SamIn, PSp] = mapminmax(p, -1, 1);   % premnmx (-1到1之間) 已被替換爲 mapminmax
[tn, PSt] = mapminmax(t, -1, 1);
SamOut = tn;         % 輸出樣本
MaxEpochs = 50000;   % 最大訓練次數
lr = 0.05;           % 學習率
E0 = 1e-3;           % 目標誤差
rng('default');
W1 = rand(HiddenUnitNum, InDim);      % 初始化輸入層與隱含層之間的權值
B1 = rand(HiddenUnitNum, 1);          % 初始化輸入層與隱含層之間的閾值
W2 = rand(OutDim, HiddenUnitNum);     % 初始化輸出層與隱含層之間的權值              
B2 = rand(OutDim, 1);                 % 初始化輸出層與隱含層之間的閾值
ErrHistory = zeros(MaxEpochs, 1);     
for i = 1 : MaxEpochs   
    HiddenOut = logsig(W1*SamIn + repmat(B1, 1, TestSamNum));   % 隱含層網絡輸出
    NetworkOut = W2*HiddenOut + repmat(B2, 1, TestSamNum);      % 輸出層網絡輸出
    Error = SamOut - NetworkOut;       % 實際輸出與網絡輸出之差
    SSE = sumsqr(Error);               % 能量函數(誤差平方和)
    ErrHistory(i) = SSE;               % 記錄每次學習的誤差
    if SSE < E0                        % 如果達到誤差閾值就退出
        break;
    end
    % 以下六行是BP網絡最核心的程序
    % 權值(閾值)依據能量函數負梯度下降原理所作的每一步動態調整量
    Delta2 = Error;
    Delta1 = W2' * Delta2 .* HiddenOut .* (1 - HiddenOut);    
    dW2 = Delta2 * HiddenOut';
    dB2 = Delta2 * ones(TestSamNum, 1); 
    dW1 = Delta1 * SamIn';
    dB1 = Delta1 * ones(TestSamNum, 1);
    % 對輸出層與隱含層之間的權值和閾值進行修正
    W2 = W2 + lr*dW2;
    B2 = B2 + lr*dB2;
    % 對輸入層與隱含層之間的權值和閾值進行修正
    W1 = W1 + lr*dW1;
    B1 = B1 + lr*dB1;
end
HiddenOut = logsig(W1*SamIn + repmat(B1, 1, TestSamNum));   % 隱含層輸出最終結果
NetworkOut = W2*HiddenOut + repmat(B2, 1, TestSamNum);      % 輸出層輸出最終結果
% tFit = postmnmx(NetworkOut, minT, maxT);    % 反歸一化,還原網絡輸出層的結果
tFit = mapminmax('reverse', NetworkOut, PSt);
x = 1 : 10;   % 序列
subplot(2, 1, 1)
plot(x, t, 'r-o', x, tFit, 'b--*');
xlabel('序列');
ylabel('數值');
% 利用訓練好的網絡進行預測
% 滾動預測後續 5 年,每次預測 1 年
ForcastSamNum = 1;
preP = zeros(1, 5);
pNew = data(end, 2:end)';    % 最後一行是輸入,豎着排
for i = 1 : 5
    pnew = pNew;  
%     pnewn = tramnmx(pnew, minP, maxP);  % 歸一化,用學習數據的最大最小值
    pnewn = mapminmax('apply', pnew, PSp);
    HiddenOut = logsig(W1*pnewn + repmat(B1, 1, ForcastSamNum));  % 隱含層輸出預測結果
    anewn = W2*HiddenOut + repmat(B2, 1, ForcastSamNum);          % 輸出層輸出預測結果
%     anew = postmnmx(anewn, minT, maxT);   % 反歸一化
    anew = mapminmax('reverse', anewn, PSt);
    preP(i) = anew;      % 保存預測值
    pNew = [pNew(2:end); anew];   % 新預測的值作爲下一次的輸入
end
% 兩條線畫一起
hold on 
plot(11:15, preP, 'b--s');
legend('真實值', '擬合值', '預測值','Location','northwest');
hold off
subplot(2, 1, 2)
plot(x, tFit - t, '--o');
hold on
plot(x, abs(tFit - t) ./ t, '--*')
hold off
legend('絕對誤差', '相對誤差');
xlabel('序列');
ylabel('絕對誤差');
% 真實值
realTfit = tFit * (maxValue - minValue) + minValue;
realPreP = preP * (maxValue - minValue) + minValue;
% disp('預測值:');
% disp(realPreP);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章