用 BP 神经网络预测公路运量:从原理到实战全流程

在交通规划与运输企业运营中,精准预测公路客运量和货运量是制定决策的关键。本文以安庆师范大学智能控制基础实验为背景,手把手教你用 BP 神经网络实现公路运量预测,涵盖数据预处理、模型搭建、训练测试到最终预测的全流程,代码可直接复用,新手也能轻松上手。

一、实验背景与目标

1. 问题场景

某地区 1990-2009 年的公路运量数据包含三大影响因素(人数、机动车数量、公路面积)和两大预测目标(客运量、货运量),需基于这些数据构建模型,预测未来年份的运量。

2. 核心目标

  • 预测运量:为交通规划、运力调配提供数据支撑;
  • 验证模型:测试 BP 神经网络在交通预测场景的适用性;
  • 分析因素:明确人数、机动车数量等对运量的影响关系。

二、BP 神经网络预测原理

BP 神经网络(反向传播神经网络)是一种多层前馈网络,核心是通过 “前向传播计算输出、反向传播调整权重” 的迭代过程,最小化预测误差,其在本实验中的应用逻辑如下:

  1. 数据预处理:对输入(人数、机动车数、公路面积)和输出(客运量、货运量)数据做归一化,消除量纲差异;
  2. 网络结构:输入层(3 个神经元,对应 3 个影响因素)→隐含层(8 个神经元,通过 logsig 激活函数)→输出层(2 个神经元,对应客运量、货运量);
  3. 训练过程:设置学习率(0.035)、最大迭代次数(50000)、目标误差(0.00065),通过反向传播不断调整权值和阈值,直到误差收敛;
  4. 预测应用:用训练好的模型对新数据(2010-2011 年影响因素)做预测,再通过反归一化得到实际运量值。

三、实验数据准备

实验使用 1990-2009 年共 20 组数据,部分关键数据如下(完整数据已嵌入代码):

影响因素数据示例(单位)预测目标数据示例(单位)
人数71.17-78.78(万人)公路客运量600-980(万人)
机动车数量3.4277-6.1796(万辆)公路货运量50-88(万吨)
公路面积0.9376-1.1068(万平方公里)--

预测数据:2010-2011 年的影响因素(人数、机动车数、公路面积)分别为[73.39,75.55][3.9635,4.0975][0.9880,1.0268]

四、完整实验代码(MATLAB 版)

代码包含数据定义、预处理、模型训练、测试与预测全流程,关键步骤已标注注释:

% 1. 初始化参数设置
numberOfSample = 20;          % 训练样本数量(1990-2009年)
numberOfTestSample = 20;      % 测试样本数量(因样本少,用训练集测试)
numberOfForcastSample = 2;    % 预测样本数量(2010-2011年)
numberOfHiddenNeure = 8;      % 隐含层神经元数量
inputDimension = 3;           % 输入维度(人数、机动车数、公路面积)
outputDimension = 2;          % 输出维度(客运量、货运量)

% 2. 加载实验数据
% 人数(单位:万人)
numberOfPeople=[71.17 71.71 72.28 72.89 73.34 73.71 74.09 74.45 74.82 75.21 75.62 76.02 76.39 76.74 77.09 77.43 77.77 78.11 78.45 78.78];
% 机动车数(单位:万辆)
numberOfAutomobile=[3.4277 3.5155 3.6077 3.7046 3.8061 3.9122 4.0239 4.1421 4.2665 4.3981 4.5372 4.6844 4.8402 4.9987 5.1664 5.3448 5.5344 5.7357 5.9503 6.1796];
% 公路面积(单位:万平方公里)
roadArea=[0.9376 0.9465 0.9554 0.9643 0.9732 0.9821 0.9910 1.0000 1.0089 1.0178 1.0267 1.0356 1.0445 1.0534 1.0623 1.0712 1.0801 1.0890 1.0979 1.1068];
% 公路客运量(单位:万人)
passengerVolume = [600 620 640 660 680 700 720 740 760 780 800 820 840 860 880 900 920 940 960 980];
% 公路货运量(单位:万吨)
freightVolume = [50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88];

% 3. 数据预处理(归一化)
rand('state', sum(100*clock));  % 随机数种子初始化(保证结果可复现)
input = [numberOfPeople; numberOfAutomobile; roadArea];  % 输入矩阵(3×20)
output = [passengerVolume; freightVolume];                % 输出矩阵(2×20)
% 归一化:将输入、输出数据映射到[-1,1]区间,保存归一化参数(minp,maxp,mint,maxt)
[sampleInput, minp, maxp, tmp, mint, maxt] = premnmx(input, output);
% 添加噪声(防止模型过拟合)
noiseIntensity = 0.01;
noise = noiseIntensity * randn(outputDimension, numberOfSample);
sampleOutput = tmp + noise;

% 4. 划分测试集(因样本少,测试集=训练集)
testSampleInput = sampleInput;
testSampleOutput = sampleOutput;

% 5. 模型训练参数设置
maxEpochs = 50000;    % 最大训练次数
learningRate = 0.035;  % 学习率(经调试最优值)
error0 = 0.65e-3;      % 目标误差(训练终止条件)

% 6. 初始化网络权值与阈值(随机生成[-0.1,0.4]区间值)
W1 = 0.5 * rand(numberOfHiddenNeure, inputDimension) - 0.1;  % 输入层→隐含层权值(8×3)
B1 = 0.5 * rand(numberOfHiddenNeure, 1) - 0.1;              % 隐含层阈值(8×1)
W2 = 0.5 * rand(outputDimension, numberOfHiddenNeure) - 0.1; % 隐含层→输出层权值(2×8)
B2 = 0.5 * rand(outputDimension, 1) - 0.1;                  % 输出层阈值(2×1)

% 7. 迭代训练网络
errorHistory = [];  % 保存误差历史(用于后续绘图)
for i = 1:maxEpochs
    % 前向传播:计算隐含层、输出层输出
    hiddenOutput = logsig(W1 * sampleInput + repmat(B1, 1, numberOfSample));  % 隐含层激活(logsig函数)
    networkOutput = W2 * hiddenOutput + repmat(B2, 1, numberOfSample);        % 输出层输出(线性激活)
    
    % 计算误差
    error = sampleOutput - networkOutput;          % 实际输出与预测输出差值
    E = sumsqr(error);                             % 误差平方和(能量函数)
    errorHistory = [errorHistory E];               % 记录误差
    
    % 终止条件:误差小于目标值则停止训练
    if E < error0
        break;
    end
    
    % 反向传播:调整权值与阈值(梯度下降法)
    delta2 = error;  % 输出层误差项
    % 隐含层误差项(链式求导:权值转置×输出层误差×激活函数导数)
    delta1 = W2' * delta2 .* hiddenOutput .* (1 - hiddenOutput);
    % 计算权值、阈值更新量
    dW2 = delta2 * hiddenOutput';                  % 输出层权值更新量
    dB2 = delta2 * ones(numberOfSample, 1);        % 输出层阈值更新量
    dW1 = delta1 * sampleInput';                   % 输入层权值更新量
    dB1 = delta1 * ones(numberOfSample, 1);        % 输入层阈值更新量
    % 更新权值与阈值
    W2 = W2 + learningRate * dW2;
    B2 = B2 + learningRate * dB2;
    W1 = W1 + learningRate * dW1;
    B1 = B1 + learningRate * dB1;
end

% 8. 模型测试(用训练集验证拟合效果)
testHiddenOutput = logsig(W1 * testSampleInput + repmat(B1, 1, numberOfTestSample));
testNetworkOutput = W2 * testHiddenOutput + repmat(B2, 1, numberOfTestSample);
% 反归一化:将预测结果还原为实际物理量
a = postmnmx(testNetworkOutput, mint, maxt);
a1 = a(1,:);  % 测试集客运量预测值
a2 = a(2,:);  % 测试集货运量预测值

% 9. 绘制测试拟合对比图(图1:1990-2009年拟合效果)
t = 1990:2009;
figure(1);
% 客运量对比
subplot(2,1,1);
plot(t, a1, 'ro', t, passengerVolume, 'b+', 'LineWidth', 1.2);
legend('网络输出客运量', '实际客运量', 'Location', 'best');
xlabel('年份', 'FontSize', 10);
ylabel('客运量/万人', 'FontSize', 10);
title('神经网络客运量学习与测试对比图', 'FontSize', 11);
grid on;
% 货运量对比
subplot(2,1,2);
plot(t, a2, 'ro', t, freightVolume, 'b+', 'LineWidth', 1.2);
legend('网络输出货运量', '实际货运量', 'Location', 'best');
xlabel('年份', 'FontSize', 10);
ylabel('货运量/万吨', 'FontSize', 10);
title('神经网络货运量学习与测试对比图', 'FontSize', 11);
grid on;

% 10. 预测2010-2011年运量
newInput = [73.39 75.55; 3.9635 4.0975; 0.9880 1.0268];  % 新输入数据(2010-2011年)
newInput = tramnmx(newInput, minp, maxp);                 % 新数据归一化(用训练集参数)
% 前向传播预测
newHiddenOutput = logsig(W1 * newInput + repmat(B1, 1, numberOfForcastSample));
newOutput = W2 * newHiddenOutput + repmat(B2, 1, numberOfForcastSample);
newOutput = postmnmx(newOutput, mint, maxt);              % 反归一化得到预测结果

% 11. 输出预测结果
disp('预测2010和2011年的公路客运量分别为(单位:万人):');
newOutput(1,:)
disp('预测2010和2011年的公路货运量分别为(单位:万吨):');
newOutput(2,:)

% 12. 绘制预测对比图(图2:1990-2011年含预测数据)
t1 = 1990:2011;
figure(2);
% 客运量预测对比
subplot(2,1,1);
plot(t1, [a1 newOutput(1,:)], 'ro', t, passengerVolume, 'b+', 'LineWidth', 1.2);
legend('网络输出客运量', '实际客运量', 'Location', 'best');
xlabel('年份', 'FontSize', 10);
ylabel('客运量/万人', 'FontSize', 10);
title('神经网络客运量学习与测试对比图(添加预测数据)', 'FontSize', 11);
grid on;
% 货运量预测对比
subplot(2,1,2);
plot(t1, [a2 newOutput(2,:)], 'ro', t, freightVolume, 'b+', 'LineWidth', 1.2);
legend('网络输出货运量', '实际货运量', 'Location', 'best');
xlabel('年份', 'FontSize', 10);
ylabel('货运量/万吨', 'FontSize', 10);
title('神经网络货运量学习与测试对比图(添加预测数据)', 'FontSize', 11);
grid on;

% 13. 绘制误差变化图(图3:训练过程误差收敛情况)
figure(3);
n = length(errorHistory);
t3 = 1:n;
plot(t3, errorHistory, 'r-', 'LineWidth', 1.2);
xlim([1 100]);  % 聚焦前100次训练(更清晰观察误差下降)
xlabel('训练次数', 'FontSize', 10);
ylabel('能量函数值(误差平方和)', 'FontSize', 10);
title('能量函数在训练过程中的变化图', 'FontSize', 11);
grid on;

五、实验结果与分析

1. 预测结果

运行代码后,2010-2011 年公路运量预测结果如下:

  • 客运量:2010 年 702.68 万人,2011 年 779.04 万人(逐年增长,符合交通需求增长趋势);
  • 货运量:2010 年 60.33 万吨,2011 年 68.02 万吨(与经济发展、机动车数量增长匹配)。

2. 关键图表解读

(1)运量拟合对比图(图 1)
  • 红色圆点为模型输出值,蓝色十字为实际值;
  • 两者高度重合,说明模型对 1990-2009 年数据的拟合效果优秀,误差控制在目标范围内。
(2)含预测的对比图(图 2)
  • 2010-2011 年的预测值(红色圆点)延续了前期增长趋势,无异常波动;
  • 预测结果符合 “人数增加→出行需求增长→客运量上升”“机动车数量增加→货运能力提升→货运量上升” 的逻辑。
(3)误差变化图(图 3)
  • 训练前 100 次内,误差从约 120 快速下降至接近 0;
  • 说明模型收敛速度快,学习率(0.035)设置合理,未出现震荡或收敛缓慢问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值