首页 > 其他分享 >数学建模_BP神经网络模型(多输入多输出)回归模型+Matlab代码包教会使用,直接替换数据即可

数学建模_BP神经网络模型(多输入多输出)回归模型+Matlab代码包教会使用,直接替换数据即可

时间:2024-11-06 13:21:10浏览次数:5  
标签:输出 num 函数 训练 模型 神经网络 train BP Matlab

BP神经网络模型(多输入多输出)回归模型

神经网络回归模型原理讲解

​ 该模型是一个典型的多层前馈神经网络(Feedforward Neural Network,FFNN),应用于回归问题。其基本原理包括数据输入、隐藏层神经元的处理、输出层的预测、以及通过反向传播算法优化权重和偏置的过程。下面将详细介绍该模型的工作原理。

1. 神经网络基础结构

神经网络的基本结构由以下几个部分组成:

  • 输入层:神经网络的输入层接受外部数据,传递给网络进行处理。在该模型中,输入层包含了五个特征变量。

  • 隐藏层:在输入和输出之间的中间层,负责提取数据中的复杂模式和非线性关系。在该模型中,隐藏层包含4个神经元。每个神经元接收输入,并对其进行处理,输出信号传递到下一个层。

  • 输出层:输出层负责将网络的最终预测结果输出。在该模型中,输出层有两个神经元,分别对应两个目标输出变量。这是一个回归任务,因此输出层的激活函数通常采用线性激活函数(purelin),它允许网络输出任意实数值。

2. 激活函数
  • 隐藏层的激活函数:tansig(双曲正切函数)

    隐藏层的每个神经元使用tansig激活函数,该函数的公式为:

    tansig ( x ) = 2 1 + e − 2 x − 1 \text{tansig}(x) = \frac{2}{1 + e^{-2x}} - 1 tansig(x)=1+e−2x2​−1
    tansig 函数的输出范围是 [-1, 1],通过该函数,神经网络可以捕捉输入数据的非线性特征。它通常用于隐藏层,因为它能够提供足够的非线性变换。

  • 输出层的激活函数:purelin(线性函数)

    输出层使用 purelin 激活函数,其公式为:

    purelin ( x ) = x \text{purelin}(x) = x purelin(x)=x
    线性激活函数适用于回归任务,因为输出值不需要进行任何非线性变换,允许模型输出任意范围的实数值。

3. 前向传播

在前向传播过程中,数据从输入层传递到输出层,每一层的神经元都会对输入信号进行加权求和,并通过激活函数产生输出信号。

  • 输入信号到隐藏层的传播

    对于输入层和隐藏层之间的连接,每个输入信号(例如 (x_1, x_2, …, x_n))都会与相应的权重(例如 (w_1, w_2, …, w_n))相乘,然后加上偏置项((b))。这称为加权和。

    隐藏层的神经元输出通过激活函数处理,公式为:
    h = tansig ( w 1 x 1 + w 2 x 2 + . . . + w n x n + b ) h = \text{tansig}(w_1 x_1 + w_2 x_2 + ... + w_n x_n + b) h=tansig(w1​x1​+w2​x2​+...+wn​xn​+b)

  • 隐藏层到输出层的传播

    输出层神经元同样通过加权和处理隐藏层的输出信号,最后通过线性激活函数得到预测值。

    输出层的预测值为:
    y pred = w h ⋅ h + b o y_{\text{pred}} = w_h \cdot h + b_o ypred​=wh​⋅h+bo​

4. 损失函数(误差函数)

回归模型的目标是最小化预测值与真实值之间的误差。常见的损失函数是均方误差(Mean Squared Error,MSE),即:
MSE = 1 n ∑ i = 1 n ( y pred , i − y true , i ) 2 \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_{\text{pred}, i} - y_{\text{true}, i})^2 MSE=n1​i=1∑n​(ypred,i​−ytrue,i​)2
通过最小化均方误差,神经网络会逐步调整权重和偏置,使得网络的预测越来越精确。

5. 训练过程:反向传播与权重更新

神经网络通过反向传播算法(Backpropagation)来训练模型。其过程如下:

  • 计算误差:首先,通过前向传播计算每个输出层神经元的预测值 (y_{\text{pred}}),并与真实值 (y_{\text{true}}) 进行比较,计算误差(例如 MSE)。

  • 反向传播:误差计算后,通过反向传播算法将误差从输出层逐层传递到输入层。每一层的权重和偏置都会根据误差的大小进行更新,以便减少整体误差。反向传播的核心是梯度下降算法,它通过计算损失函数的梯度来更新权重和偏置。

    更新规则为:
    w = w − η ⋅ ∂ E ∂ w w = w - \eta \cdot \frac{\partial E}{\partial w} w=w−η⋅∂w∂E​

  • 迭代优化:这个过程会迭代多次(在代码中是通过设置最大训练次数),每次迭代都会对网络的权重进行微小的调整,最终使得网络的误差达到最小。

6. 训练与预测

在该模型中,训练集数据用于优化神经网络的权重和偏置,而测试集数据用于评估训练后的模型性能。模型的输出是对于目标变量的预测值,训练过程中的误差指标(如均方根误差、R²、MAE)能够帮助判断模型的预测效果。

总结
  • 该模型是一个标准的多层前馈神经网络(FFNN),用于回归问题。
  • 输入数据通过隐藏层的激活函数进行非线性变换,最终在输出层得到预测值。
  • 网络通过反向传播算法来调整权重和偏置,使得误差最小化。
  • 该模型适用于预测连续值,能够学习复杂的非线性关系。

神经网络回归模型原理讲解(结合代码)

该代码实现了一个多层前馈神经网络(Feedforward Neural Network,FFNN)用于回归任务,目标是基于给定的特征数据(输入)预测两个连续的输出。下面详细讲解每个部分的原理,并结合代码进行解释。

1. 导入数据并归一化处理
res = readmatrix('回归数据.xlsx');  % 导入数据
X = res(:, 1:5);  % 特征变量
Y = res(:, 6:7);  % 目标变量
x = mapminmax(X', 0, 1);  % 对特征变量归一化
[y, psout] = mapminmax(Y', 0, 1);  % 对目标变量归一化
  • 数据导入:首先通过 readmatrix 导入回归数据集,其中 X 是输入特征(例如,5个特征变量),Y 是目标输出(例如,2个回归输出变量)。
  • 数据归一化:使用 mapminmax 函数对输入特征和目标输出进行归一化处理,使得数据都映射到[0, 1]范围内。这是神经网络中常见的数据预处理方式,能够加速训练过程,避免某些特征值过大导致梯度消失或梯度爆炸的问题。
2. 划分训练集与测试集
num = size(res, 1);  % 获取数据的总行数
state = randperm(num);  % 随机打乱样本的索引
ratio = 0.8;  % 训练集占比
train_num = floor(num * ratio);  % 计算训练集的样本数量

x_train = x(:, state(1:train_num));  % 训练集特征
y_train = y(:, state(1:train_num));  % 训练集目标
x_test = x(:, state(train_num+1:end));  % 测试集特征
y_test = y(:, state(train_num+1:end));  % 测试集目标
  • 随机打乱数据randperm(num) 生成一个随机排列的索引,然后使用这些索引来打乱数据。这样可以避免因数据顺序性带来的偏差。
  • 划分数据集:通过设定 80% 的数据用于训练,20% 的数据用于测试,分割训练集和测试集。
3. 创建神经网络
hiddens = 4;  % 隐藏层神经元个数
tf = {'tansig', 'purelin'};  % 激活函数,隐藏层用tansig,输出层用purelin
net = newff(x_train, y_train, hiddens, tf);  % 创建神经网络
  • 神经网络结构:代码使用 newff 函数来创建一个前馈神经网络。该函数是 MATLAB 中用于创建多层前馈神经网络的标准函数。网络结构包含:
    • 输入层:有5个节点,对应5个输入特征。
    • 隐藏层:一个隐藏层,包含4个神经元(在代码中由 hiddens = 4 设置)。该层使用 tansig(双曲正切)作为激活函数,它能提供非线性映射,从而帮助网络捕捉复杂的关系。
    • 输出层:使用 purelin 作为激活函数,这表示输出层是线性的,适合回归任务。
4. 设置训练参数
net.trainParam.epochs = 1000;     % 训练迭代次数MAX
net.trainParam.goal = 1e-6;       % 目标误差
net.trainParam.lr = 0.01; 
  • 训练参数
    • epochs:设置网络的最大迭代次数,即最多训练1000次。
    • goal:指定目标误差,当网络的均方误差(MSE)小于 1e-6 时,训练就会停止。
    • lr:学习率,决定了每次参数更新时步长的大小。
5. 训练神经网络
net = train(net, x_train, y_train);  % 训练神经网络
  • 训练过程train 函数使用训练数据(x_trainy_train)来优化神经网络的权重和偏置。通过多次迭代,网络学习到输入特征与输出目标之间的关系。
6. 仿真测试
re1 = sim(net, x_train);
re2 = sim(net, x_test);
  • 仿真预测:通过 sim 函数,在训练集和测试集上分别进行预测,得到网络输出的预测结果。
7. 数据反归一化
pre1 = mapminmax('reverse', re1, psout);
pre2 = mapminmax('reverse', re2, psout);
  • 反归一化:将归一化的预测结果通过 mapminmax('reverse', ...) 转换回原始的尺度,得到实际的预测值。
8. 评估模型性能
% 计算误差和相关指标
error1 = sqrt(mean((p1 - Y_tr).^2)); % RMSE
R1 = 1 - norm(Y_tr - p1)^2 / norm(Y_tr - mean(Y_tr))^2;  % R2
mae1 = mean(abs(Y_tr - p1));  % MAE
  • 误差计算:计算了多个回归模型的性能指标:
    • RMSE(均方根误差):反映了预测值与真实值之间的差异,值越小表示模型性能越好。
    • R²(决定系数):表示模型的拟合优度,R² 越接近 1,表示模型拟合得越好。
    • MAE(平均绝对误差):计算预测值与真实值之间的平均绝对差异。
9. 绘图与结果展示
plot(1: trainnum, Y_tr, 'r-^', 1: trainnum, p1, 'b-+', 'LineWidth', 1)
plot(1: testnum, Y_te, 'r-^', 1: testnum, p2, 'b-+', 'LineWidth', 1)
  • 结果对比图:通过 plot 函数绘制训练集和测试集的真实值与预测值的对比图,以及误差曲线图和拟合图,直观地展示模型的预测效果。
总结:

该神经网络回归模型的流程包括:

  1. 数据预处理:对输入特征和目标进行归一化。
  2. 网络构建:使用 newff 创建一个具有1个隐藏层的多层前馈神经网络。
  3. 训练过程:使用训练集数据训练神经网络,学习输入和输出之间的关系。
  4. 仿真与预测:在训练集和测试集上进行预测,反归一化得到实际预测值。
  5. 模型评估:通过计算误差指标(RMSE、R²、MAE)来评估模型的性能,并通过图表展示结果。

该模型适用于需要回归预测的任务,可以通过调整网络的隐藏层神经元数、学习率等超参数来优化模型性能。

Matlab代码手把手教运行

为了帮助更多的萌新更快上手数学建模建等竞赛,这里直接手把手教会如何直接使用本文中的BP神经网络代码:

close all;clear;clc;
rng(5676)

res = readmatrix('回归数据.xlsx');

X = res(:,1:5);
Y = res(:,6:7);
x = mapminmax(X', 0, 1);
[y, psout] = mapminmax(Y', 0, 1);

num = size(res,1);
state = randperm(num); 
ratio = 0.8; 
train_num = floor(num*ratio);

x_train = x(:,state(1: train_num));
y_train = y(:,state(1: train_num));
trainnum = size(x_train, 2);

x_test = x(:,state(train_num+1: end));
y_test = y(:,state(train_num+1: end));
testnum = size(x_test, 2);

hiddens = 4; %隐藏层个数
tf = {'tansig', 'purelin'};
net = newff(x_train, y_train, hiddens,tf);

%%  设置参数
net.trainParam.epochs = 1000;    
net.trainParam.goal = 1e-6;    
net.trainParam.lr = 0.01;       

%%  训练网络
net= train(net, x_train, y_train);


re1 = sim(net, x_train);
re2 = sim(net, x_test );


Y_train = Y(state(1: train_num),:)';
Y_test = Y(state(train_num+1:end),:)';


pre1 = mapminmax('reverse', re1, psout);
pre2 = mapminmax('reverse', re2, psout);


for i=1:2
    disp('        ')
    disp('        ')
    disp(['第',num2str(i),'个输出指标'])
    p1 = pre1(i,:);
    p2 = pre2(i,:);
    Y_tr = Y_train(i,:);
    Y_te = Y_test(i,:);
    

    error1 = sqrt(mean((p1 - Y_tr).^2));
    error2 = sqrt(mean((p2 - Y_te).^2));
    

    R1 = 1 - norm(Y_tr - p1)^2 / norm(Y_tr - mean(Y_tr))^2;
    R2 = 1 - norm(Y_te -  p2)^2 / norm(Y_te -  mean(Y_te ))^2;
    

    mae1 = mean(abs(Y_tr - p1 ));
    mae2 = mean(abs(p2 - Y_te ));
    
    disp('训练集预测精度指标如下:')
    disp(['训练集数据的R2为:', num2str(R1)])
    disp(['训练集数据的MAE为:', num2str(mae1)])
    disp(['训练集数据的RMSE为:', num2str(error1)])
    disp('测试集预测精度指标如下:')
    disp(['测试集数据的R2为:', num2str(R2)])
    disp(['测试集数据的MAE为:', num2str(mae2)])
    disp(['测试集数据的RMSE为:', num2str(error2)])
    
    figure
    plot(1: trainnum, Y_tr, 'r-^', 1: trainnum, p1, 'b-+', 'LineWidth', 1)
    legend('真实值','预测值')
    xlabel('样本点')
    ylabel('预测值')
    title('训练集预测结果对比')
    

    figure
    plot(1: testnum, Y_te, 'r-^', 1: testnum, p2, 'b-+', 'LineWidth', 1)
    legend('真实值','预测值')
    xlabel('样本点')
    ylabel('预测值')
    title('测试集预测结果对比')

    figure
    plot((p1 - Y_tr )./Y_tr, 'b-o', 'LineWidth', 1)
    legend('百分比误差')
    xlabel('样本点')
    ylabel('误差')
    title('训练集百分比误差曲线')

    figure
    plot((p2 - Y_te )./Y_te, 'b-o', 'LineWidth', 1)
    legend('百分比误差')
    xlabel('样本点')
    ylabel('误差')
    title('测试集百分比误差曲线')

    figure;
    plotregression(Y_tr, p1, '训练集', ...
                   Y_te, p2, '测试集');
    set(gcf,'Toolbar','figure');
end

回归数据.xlsx:

x1x2x3x4x5y1y2
3.0362265613.881217.47568.4348316.8209348.4790761239.33407612
4.3916588450.278231.623160.4768310.720564.1218518554.97685185
5.2485978634.475232.985468.7401111.5485667.6714873458.52648734
5.1212367253.694244.469265.3606114.3619159.3275305750.18253057
4.6490218647.125268.305263.8013212.0485767.9857039158.84070391
4.2672095445.033257.770161.689977.05562546.4750659837.33006598
4.8045125848.875234.096867.144677.65613447.1844257938.03942579
3.8258036583.543270.757561.4445316.6565454.048729644.9037296
4.7875349546.304225.827967.8935111.4366569.9037230960.75872309
5.5807975481.803287.904362.2043211.2692747.3201295738.17512957
3.6589199482.116278.809361.2021712.3741871.6842969562.53929695
3.8299859128.034225.218764.8142316.7046168.1873542759.04235427
5.2957856804.695282.694767.1343413.6187158.030937648.8859376

替换数据只需将特征值放入前几列(第一行为列名),因变脸放在后面即可,接下来调整一下代码即可:

X = res(:,1:5);
Y = res(:,6:7);//在第几列就写几到几

后续继续免费更新模型代码,祝好运!

标签:输出,num,函数,训练,模型,神经网络,train,BP,Matlab
From: https://blog.csdn.net/2401_82466443/article/details/143568150

相关文章

  • Ollama AI 框架缺陷可能导致 DoS、模型盗窃和中毒
    近日,东方联盟网络安全研究人员披露了Ollama人工智能(AI)框架中的六个安全漏洞,恶意行为者可能会利用这些漏洞执行各种操作,包括拒绝服务、模型中毒和模型盗窃。知名网络安全专家、东方联盟创始人郭盛华表示:“总的来说,这些漏洞可能允许攻击者通过单个HTTP请求执行各种恶意操......
  • 笔记--(网络1)、网络参考模型,数值转换
    常见术语术语说明数据载荷最终想要传递的信息报文网络重交换与传输的数据单元头部在数据载荷的前面添加的信息段尾部在数据载荷的后面添加信息段封装对数据载荷添加头部和尾部,形成新的报文的过程解封装去掉报文的头部和尾部,获取数据载荷的过程网关提供协议转换、路由选择、......
  • Java中的I/O模型——BIO、NIO、AIO
    1. BIO(BlockingI/O)1. 1BIO(BlockingI/O)模型概述        BIO,即“阻塞I/O”(BlockingI/O),是一种同步阻塞的I/O模式。它的主要特点是,当程序发起I/O请求(比如读取数据或写入数据)时,程序会一直等到这个请求完成,才继续往下执行。在BIO模型下,每个连接都需要一个独立的线程......
  • KBP312-ASEMI小电流超高电压整流桥1200V
    编辑:llKBP312-ASEMI小电流超高电压整流桥1200V型号:KBP312品牌:ASEMI封装:KBP-4批号:2024+现货:50000+最大重复峰值反向电压:1200V最大正向平均整流电流(Vdss):3A功率(Pd):小功率芯片个数:4引脚数量:4安装方式:插件类型:插件扁桥、整流桥正向浪涌电流IFSM:50A正向电压:1.00V~1.10......
  • 基于【PSINS工具箱】提供一个MATLAB例程,仅以速度为观测量的SINS/GNSS组合导航
    基于【PSINS工具箱】,提供一个MATLAB例程,仅以速度为观测量的SINS/GNSS组合导航(滤波方式可选EKF/UKF/CKF),无需下载,订阅专栏后可直接复制文章目录工具箱程序简述运行结果程序源代码程序讲解代码功能概述代码结构与关键步骤结论工具箱本程序需要在安装工具箱后使用,......
  • 07LangChain实战课 - LLM模块使用与自定义模型调用
    LangChain实战课-LLM模块使用与自定义模型调用1.课程简介本节课聚焦于LangChain中的LLM(LargeLanguageModel)模块,探讨如何使用不同的大语言模型,包括开源模型和自定义模型。2.大语言模型的发展Transformer架构:Google在2018年提出的架构,是现代预训练模型的核心。基础......
  • 基于条件风险价值CVaR的微网动态定价与调度策略(Matlab代码实现)
    ......
  • 质子交换膜燃料电池(PEMFC Simulink模型)
        ......