ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

MATLAB神经网络建模实战:从数据预处理到模型部署的完整流程

MATLAB神经网络建模实战:从数据预处理到模型部署的完整流程 1. 从零到一MATLAB神经网络建模的完整工作流如果你正在准备数学建模竞赛或者课程项目需要一个能跑出结果的神经网络模型那么“可执行代码”这几个字可能就是你的救命稻草。我见过太多同学在网上找了一堆理论下载了几个代码片段结果不是环境报错就是数据对不上最后只能对着屏幕干瞪眼。今天我们不谈空洞的理论就聚焦一件事如何用MATLAB从一张白纸开始写出一段能直接运行、能出结果、甚至能直接拿去交差的神经网络建模代码。这不仅仅是写几行命令那么简单。一个完整的、可执行的建模流程至少包含五个环环相扣的环节环境与数据准备、模型选择与构建、训练与调参、结果评估与可视化、以及最终的代码封装与报告生成。很多教程只讲中间“训练”那一步把头尾都省了导致你永远无法独立完成一个项目。本文将严格遵循这个完整链条我会把每个环节中那些“默认你会但实际上你可能不会”的细节掰开揉碎并提供可以直接复制粘贴的代码块。我们的目标很明确让你拿到一套“开箱即用”的方法论和代码框架。2. 起手式数据预处理与MATLAB环境确认在激动地敲下feedforwardnet之前90%的失败已经注定原因都出在数据和环境上。这一步枯燥但至关重要它决定了你的模型是“科学实验”还是“玄学调试”。2.1 数据导入与清洗实战数学建模中的数据来源五花八门可能是Excel、CSV、TXT甚至是数据库。MATLAB处理这些数据非常方便但陷阱也不少。% 假设我们有一个名为‘competition_data.xlsx’的文件第一个工作表是数据 rawData readtable(‘competition_data.xlsx’); % 使用readtable保持列名信息 % 查看数据概览这是第一步千万别跳过 summary(rawData); disp(‘数据前5行’); disp(rawData(1:5, :)); % 处理缺失值这是建模中最常见的问题之一 % 方法1删除含有缺失值的行数据量足够大时 cleanData rmmissing(rawData); % 方法2用均值/中位数填充更常用 % 例如填充第二列假设是数值型的缺失值 col2 rawData{:, 2}; col2(isnan(col2)) mean(col2, ‘omitnan’); rawData{:, 2} col2; % 检查异常值简单的3σ原则 for i 1:width(cleanData) if isnumeric(cleanData{:, i}) colMean mean(cleanData{:, i}); colStd std(cleanData{:, i}); outliers abs(cleanData{:, i} - colMean) 3 * colStd; if any(outliers) fprintf(‘列 %d 发现 %d 个潜在异常值。\n’, i, sum(outliers)); % 通常建议查看而非直接删除可能包含重要信息 end end end一个关键心得对于数学建模永远保留一份原始数据的副本。所有清洗操作都应在副本上进行并在代码中清晰注释每一步操作的原因例如“根据题目要求剔除2020年之前的异常记录”。这能让你的论文可复现也是评委看重的地方。2.2 特征与标签分离以及归一化神经网络对输入数据的尺度非常敏感。大的数值范围会主导梯度导致模型难以收敛。因此归一化是标准操作。% 假设我们的表格中最后一列‘label’是我们要预测的标签因变量 % 其他列都是特征自变量 features cleanData{:, 1:end-1}; % 提取所有行除最后一列外的所有列 labels cleanData{:, end}; % 提取最后一列作为标签 % 数据归一化使用 mapminmax 函数归一化到[-1, 1]区间 % 注意一定要先对训练集拟合参数再用同样的参数变换测试集 % 这里我们先整体做实际中应在划分训练测试集后进行。 [featuresNorm, ps_input] mapminmax(features‘, -1, 1); % mapminmax处理的是行样本所以先转置 featuresNorm featuresNorm‘; % 转置回来恢复为 [样本数×特征数] 的矩阵 [labelsNorm, ps_output] mapminmax(labels‘, -1, 1); labelsNorm labelsNorm‘; % 保存预处理参数ps_input和ps_output在预测新数据时使用 save(‘preprocess_params.mat‘, ‘ps_input‘, ‘ps_output‘);这里有个大坑绝对不能在整个数据集上做归一化后再划分训练集和测试集。这会导致数据泄露Data Leakage即测试集的信息“污染”了训练过程使模型评估结果虚高。正确的做法是先划分再分别用训练集的统计量最大值、最小值去归一化训练集和测试集。2.3 数据集划分策略% 设置随机种子确保结果可复现 rng(2024); % 决定划分比例常见的是 70%训练15%验证15%测试 trainRatio 0.7; valRatio 0.15; testRatio 0.15; % 计算各集合的样本数 numSamples size(featuresNorm, 1); numTrain round(trainRatio * numSamples); numVal round(valRatio * numSamples); numTest numSamples - numTrain - numVal; % 随机打乱索引 indices randperm(numSamples); % 划分索引 trainInd indices(1:numTrain); valInd indices(numTrain1:numTrainnumVal); testInd indices(numTrainnumVal1:end); % 创建最终的数据集 xTrain featuresNorm(trainInd, :); tTrain labelsNorm(trainInd, :); xVal featuresNorm(valInd, :); tVal labelsNorm(valInd, :); xTest featuresNorm(testInd, :); tTest labelsNorm(testInd, :); % 保存划分好的数据集方便后续调用 save(‘split_data.mat‘, ‘xTrain‘, ‘tTrain‘, ‘xVal‘, ‘tVal‘, ‘xTest‘, ‘tTest‘);验证集Validation Set的作用经常被忽视。它不参与最终权重更新而是在每个训练周期Epoch后用来评估模型当前的表现主要用于监控模型是否过拟合以及作为早停Early Stopping和超参数调优的依据。没有验证集你的调参就是盲人摸象。3. 核心构建选择与搭建你的神经网络数据准备好了现在进入核心环节造模型。MATLAB的神经网络工具箱非常强大但对于新手面对patternnet,fitnet,feedforwardnet这些函数可能会懵。我们以最常用的前馈神经网络BP神经网络和拟合回归问题为例。3.1 创建网络对象理解fitnet的隐藏参数fitnet是用于函数拟合回归问题的前馈网络创建函数。它的第一个参数是隐藏层神经元个数可以是一个数组来定义多层。% 创建一个单隐藏层包含10个神经元的拟合网络 hiddenLayerSize 10; net fitnet(hiddenLayerSize); % 查看网络结构 view(net)运行view(net)会弹出一个框图直观展示输入-隐藏层-输出的连接。但创建网络只是第一步更重要的是配置它的训练参数这些参数藏在net.trainParam和net.divideParam里。% 1. 设置数据划分函数我们已经手动划分好了所以这里要告诉网络 net.divideFcn ‘divideind‘; % 使用索引划分 net.divideParam.trainInd trainInd; net.divideParam.valInd valInd; net.divideParam.testInd testInd; % 2. 配置关键训练参数 net.trainParam.epochs 1000; % 最大训练迭代次数 net.trainParam.goal 1e-5; % 训练目标误差均方误差 net.trainParam.lr 0.01; % 学习率 (Learning Rate) net.trainParam.showWindow true; % 显示训练进度窗口 net.trainParam.showCommandLine false; % 不在命令行显示 net.trainParam.max_fail 20; % 验证集误差连续上升次数用于早停 % 3. 可选选择训练算法 % net.trainFcn ‘trainlm‘; % Levenberg-Marquardt默认快但耗内存 % net.trainFcn ‘trainbr‘; % Bayesian Regularization抗过拟合好但慢 % net.trainFcn ‘trainscg‘; % Scaled Conjugate Gradient内存友好关于训练算法的选择这是第一个需要你根据实际情况做决策的点。trainlm默认对于中小型数据集几百个样本通常是首选收敛速度极快。但如果你的数据量很大上万或者特征很多它可能会耗尽内存。trainbr贝叶斯正则化。这是我个人在数学建模中非常推荐的一种算法因为它自带防止过拟合的正则化效果。在数据量有限、模型可能复杂时它能给出更稳健的预测。代价是训练速度慢。trainscg缩放共轭梯度法。在内存受限或数据集非常大时使用。它不需要计算海森矩阵节省内存。对于数学建模我建议你先用trainlm快速跑通流程如果发现验证集误差很早就开始上升过拟合迹象再换用trainbr试试。3.2 网络训练与过程监控配置好后训练就是一行命令但如何解读训练窗口里的信息是关键。% 开始训练注意输入x和目标t都需要是转置后的 [特征数×样本数] 格式 % 这是MATLAB神经网络工具箱的一个常见易错点 [net, tr] train(net, xTrain‘, tTrain‘);训练会弹出一个窗口里面有四条曲线蓝色实线Training训练集误差。它应该持续下降。绿色虚线Validation验证集误差。这是最重要的曲线。它的变化趋势揭示了模型的泛化能力。理想情况训练误差和验证误差一起平稳下降最后都趋于平缓且值接近。过拟合训练误差持续下降但验证误差在某个点后开始持续上升。这意味着模型记住了训练数据的噪声而非规律。max_fail参数就是监控这个的验证误差连续上升max_fail次后训练会自动停止早停并返回验证误差最低的那个模型状态。欠拟合两条误差曲线都很高且下降缓慢或很早就停滞了。说明模型复杂度不够无法捕捉数据中的规律。红色虚线Test测试集误差。在训练过程中测试集完全不参与它的曲线只是用来最终参考。训练结束后我们用测试集做最终的唯一评估。黑色点虚线Goal目标误差线。训练结束后tr结构体包含了详细的训练记录如tr.best_epoch最佳验证性能对应的迭代次数这个信息对于写论文分析非常有用。4. 模型评估、预测与可视化模型训练好了怎么知道它行不行不能光靠感觉必须用数据说话。4.1 进行预测与反归一化% 使用训练好的网络进行预测同样要注意转置 yTrainPred net(xTrain‘); yValPred net(xVal‘); yTestPred net(xTest‘); % 将预测值从归一化空间转换回原始数据空间 yTrainPred_original mapminmax(‘reverse‘, yTrainPred, ps_output); yValPred_original mapminmax(‘reverse‘, yValPred, ps_output); yTestPred_original mapminmax(‘reverse‘, yTestPred, ps_output); % 同样将真实标签也反归一化方便对比 tTrain_original mapminmax(‘reverse‘, tTrain‘, ps_output); tVal_original mapminmax(‘reverse‘, tVal‘, ps_output); tTest_original mapminmax(‘reverse‘, tTest‘, ps_output);切记所有评估指标如RMSE, R²都应在反归一化后的原始数据上计算。在归一化后的数据上计算指标会严重失真没有实际意义。4.2 关键评估指标计算与解读对于回归问题最常用的几个指标如下% 计算均方根误差 (RMSE) - 衡量预测值与真实值的平均偏差单位与y相同 rmse_train sqrt(mean((yTrainPred_original - tTrain_original).^2)); rmse_test sqrt(mean((yTestPred_original - tTest_original).^2)); % 计算平均绝对百分比误差 (MAPE) - 相对误差适合不同量级数据的比较 mape_train mean(abs((yTrainPred_original - tTrain_original) ./ tTrain_original)) * 100; mape_test mean(abs((yTestPred_original - tTest_original) ./ tTest_original)) * 100; % 计算决定系数 (R-squared, R²) - 衡量模型对数据波动的解释能力 % R² 1 - (SS_residual / SS_total) ss_res_train sum((tTrain_original - yTrainPred_original).^2); ss_tot_train sum((tTrain_original - mean(tTrain_original)).^2); r2_train 1 - (ss_res_train / ss_tot_train); ss_res_test sum((tTest_original - yTestPred_original).^2); ss_tot_test sum((tTest_original - mean(tTest_original)).^2); r2_test 1 - (ss_res_test / ss_tot_test); fprintf(‘训练集 — RMSE: %.4f, MAPE: %.2f%%, R²: %.4f\n‘, rmse_train, mape_train, r2_train); fprintf(‘测试集 — RMSE: %.4f, MAPE: %.2f%%, R²: %.4f\n‘, rmse_test, mape_test, r2_test);如何解读RMSE越小越好。对比你预测目标的实际取值范围如果RMSE只有取值范围的百分之几通常说明模型不错。MAPE小于10%通常认为预测精度较高但也要看具体领域。R²取值范围在0到1之间也可能为负说明模型比直接用均值预测还差。越接近1越好。在数学建模论文中R²是一个非常有说服力的指标。关键要看测试集的R²它才是模型泛化能力的真实反映。如果训练集R²很高0.95而测试集R²很低0.6那就是典型的过拟合。4.3 结果可视化让评委一眼看懂一图胜千言在论文中放入高质量的分析图能极大提升印象分。figure(‘Position‘, [100, 100, 1200, 400]); % 设置大图窗 % 子图1预测值 vs 真实值散点图 完美预测线 subplot(1, 3, 1); scatter(tTest_original, yTestPred_original, 20, ‘b‘, ‘filled‘); hold on; plot([min(tTest_original), max(tTest_original)], [min(tTest_original), max(tTest_original)], ‘r--‘, ‘LineWidth‘, 2); hold off; xlabel(‘真实值‘); ylabel(‘预测值‘); title(sprintf(‘测试集预测 vs 真实 (R²%.3f)‘, r2_test)); grid on; legend(‘数据点‘, ‘yx 参考线‘, ‘Location‘, ‘best‘); % 子图2误差分布直方图 subplot(1, 3, 2); errors yTestPred_original - tTest_original; histogram(errors, 20, ‘FaceColor‘, ‘g‘, ‘EdgeColor‘, ‘k‘); xlabel(‘预测误差‘); ylabel(‘频数‘); title(‘测试集误差分布‘); grid on; % 在图上标注均值和标准差 mean_err mean(errors); std_err std(errors); text(0.7, 0.9, sprintf(‘均值: %.3f\n标准差: %.3f‘, mean_err, std_err), ... ‘Units‘, ‘normalized‘, ‘FontSize‘, 10, ‘BackgroundColor‘, ‘w‘); % 子图3按样本顺序的预测对比图 subplot(1, 3, 3); sampleIndex 1:length(tTest_original); plot(sampleIndex, tTest_original, ‘b-o‘, ‘LineWidth‘, 1.5, ‘MarkerSize‘, 4, ‘DisplayName‘, ‘真实值‘); hold on; plot(sampleIndex, yTestPred_original, ‘r-s‘, ‘LineWidth‘, 1.5, ‘MarkerSize‘, 4, ‘DisplayName‘, ‘预测值‘); hold off; xlabel(‘测试样本序号‘); ylabel(‘数值‘); title(‘测试集样本对比‘); legend(‘Location‘, ‘best‘); grid on;这三张图构成了一个完整的评估视图散点图看整体相关性直方图看误差是否服从正态分布理想情况样本对比图看模型在局部细节上的拟合能力。5. 模型调优与集成从能用变到好用如果你的基线模型比如单隐层10神经元效果不理想别急着放弃。神经网络有大量的“旋钮”可以调节。5.1 超参数调优实战网格搜索与交叉验证手动调参效率低我们可以用简单的循环实现网格搜索。这里以调整隐藏层神经元数量和训练算法为例。% 定义要搜索的参数组合 hiddenSizes {5, 10, 15, [5, 5], [10, 5]}; % 尝试不同结构 trainFcns {‘trainlm‘, ‘trainbr‘, ‘trainscg‘}; % 初始化存储最佳结果的变量 bestR2 -inf; bestNet []; bestParams struct(‘hiddenSize‘, [], ‘trainFcn‘, ‘‘); fprintf(‘开始超参数网格搜索...\n‘); for i 1:length(hiddenSizes) for j 1:length(trainFcns) fprintf(‘测试组合: 隐藏层 %s, 算法 %s ... ‘, mat2str(hiddenSizes{i}), trainFcns{j}); % 创建网络 net_temp fitnet(hiddenSizes{i}, trainFcns{j}); net_temp.divideFcn ‘divideind‘; net_temp.divideParam.trainInd trainInd; net_temp.divideParam.valInd valInd; net_temp.divideParam.testInd testInd; net_temp.trainParam.showWindow false; % 关闭窗口加速 net_temp.trainParam.showCommandLine false; % 训练网络 [net_temp, tr_temp] train(net_temp, xTrain‘, tTrain‘); % 在测试集上评估 yPred_temp net_temp(xTest‘); yPred_original_temp mapminmax(‘reverse‘, yPred_temp, ps_output); % 计算R² ss_res sum((tTest_original - yPred_original_temp).^2); ss_tot sum((tTest_original - mean(tTest_original)).^2); r2_temp 1 - (ss_res / ss_tot); fprintf(‘测试集 R² %.4f\n‘, r2_temp); % 记录最佳模型 if r2_temp bestR2 bestR2 r2_temp; bestNet net_temp; bestParams.hiddenSize hiddenSizes{i}; bestParams.trainFcn trainFcns{j}; end end end fprintf(‘\n最佳参数组合\n‘); fprintf(‘ 隐藏层结构: %s\n‘, mat2str(bestParams.hiddenSize)); fprintf(‘ 训练算法: %s\n‘, bestParams.trainFcn); fprintf(‘ 测试集 R²: %.4f\n‘, bestR2);这个简单的网格搜索能帮你快速定位一个相对较好的参数范围。更高级的方法可以使用MATLAB的优化工具箱或手动实现贝叶斯优化。5.2 集成学习用简单方法提升稳定性单个神经网络可能不稳定特别是对于小数据集。集成多个模型可以降低方差提升泛化能力。这里实现一个简单的Bagging自助聚合方法。numModels 10; % 集成10个模型 ensemblePredictions zeros(size(yTestPred_original)); for m 1:numModels fprintf(‘训练集成模型 %d/%d...\n‘, m, numModels); % 1. 自助采样 (Bootstrap Sampling)从训练集中有放回地随机抽取同样数量的样本 bootstrapIndices randsample(length(trainInd), length(trainInd), true); xTrain_boot xTrain(bootstrapIndices, :); tTrain_boot tTrain(bootstrapIndices, :); % 2. 训练一个基学习器使用之前找到的最佳参数 net_ensemble fitnet(bestParams.hiddenSize, bestParams.trainFcn); net_ensemble.divideFcn ‘divideind‘; % 注意这里我们用自助采样集训练但验证集和测试集不变用于早停和最终评估 net_ensemble.divideParam.trainInd 1:size(xTrain_boot,1); net_ensemble.divideParam.valInd []; % 为了简化这里不用验证集实际可划分 net_ensemble.divideParam.testInd []; net_ensemble.trainParam.showWindow false; % 3. 训练 [net_ensemble, ~] train(net_ensemble, xTrain_boot‘, tTrain_boot‘); % 4. 在测试集上预测并反归一化 yPred_temp net_ensemble(xTest‘); yPred_original_temp mapminmax(‘reverse‘, yPred_temp, ps_output); ensemblePredictions ensemblePredictions yPred_original_temp; end % 5. 取平均作为集成模型的最终预测 ensemblePredictions ensemblePredictions / numModels; % 6. 评估集成模型 ss_res_ensemble sum((tTest_original - ensemblePredictions).^2); ss_tot_ensemble sum((tTest_original - mean(tTest_original)).^2); r2_ensemble 1 - (ss_res_ensemble / ss_tot_ensemble); rmse_ensemble sqrt(mean((tTest_original - ensemblePredictions).^2)); fprintf(‘\n集成模型%d个结果\n‘, numModels); fprintf(‘ 测试集 R²: %.4f\n‘, r2_ensemble); fprintf(‘ 测试集 RMSE: %.4f\n‘, rmse_ensemble);集成学习几乎总能带来一点性能提升更重要的是它让结果更稳定。在论文中你可以对比单一模型和集成模型的R²和RMSE并讨论稳定性的提升。6. 代码封装、部署与论文写作要点模型满意了最后一步是把它打包成一个完整的、可交付的项目。6.1 创建可复现的主脚本与函数不要把所有代码堆在一个脚本里。一个好的实践是创建主脚本和若干函数文件。主脚本main_neural_network_modeling.m%% MATLAB神经网络数学建模可执行代码 - 主脚本 % 作者[你的名字] % 日期2024-05-27 % 描述用于[具体问题如房价预测、销量预测]的BP神经网络建模全流程 clear; close all; clc; % 清空环境 addpath(‘./utils‘); % 添加工具函数路径 %% 第一步数据加载与预处理 fprintf(‘第一步数据加载与预处理...\n‘); [features, labels, ps_input, ps_output] load_and_preprocess(‘your_data.csv‘); %% 第二步数据集划分 fprintf(‘第二步数据集划分...\n‘); [xTrain, tTrain, xVal, tVal, xTest, tTest, trainInd, valInd, testInd] ... split_dataset(features, labels, 0.7, 0.15, 0.15); %% 第三步模型训练 fprintf(‘第三步模型训练...\n‘); [net, tr] train_neural_network(xTrain, tTrain, xVal, tVal, trainInd, valInd, testInd); %% 第四步模型评估与可视化 fprintf(‘第四步模型评估...\n‘); metrics evaluate_model(net, xTest, tTest, ps_output); plot_results(net, xTest, tTest, ps_output, metrics); %% 第五步可选模型保存 save(‘trained_neural_network_model.mat‘, ‘net‘, ‘ps_input‘, ‘ps_output‘, ‘tr‘, ‘metrics‘); fprintf(‘模型已保存至 trained_neural_network_model.mat\n‘); %% 第六步使用模型预测新数据示例 % load(‘trained_neural_network_model.mat‘); % 加载已保存的模型 % newData [1.2, 3.4, 5.6; ...]; % 新数据需要与训练数据特征数相同 % prediction predict_with_model(net, newData, ps_input, ps_output); % fprintf(‘新数据的预测结果为%.4f\n‘, prediction);工具函数示例utils/evaluate_model.mfunction metrics evaluate_model(net, xTest, tTest, ps_output) % 评估模型在测试集上的性能 % 输入训练好的网络net测试集输入xTest测试集目标tTest输出归一化参数ps_output % 输出包含各项评估指标的结构体metrics % 预测 yTestPred net(xTest‘); yTestPred_original mapminmax(‘reverse‘, yTestPred, ps_output); tTest_original mapminmax(‘reverse‘, tTest‘, ps_output); % 计算指标 errors yTestPred_original - tTest_original; metrics.RMSE sqrt(mean(errors.^2)); metrics.MAE mean(abs(errors)); metrics.MAPE mean(abs(errors ./ tTest_original)) * 100; ss_res sum(errors.^2); ss_tot sum((tTest_original - mean(tTest_original)).^2); metrics.R2 1 - (ss_res / ss_tot); % 打印结果 fprintf(‘\n 模型评估结果 \n‘); fprintf(‘均方根误差 (RMSE): %.4f\n‘, metrics.RMSE); fprintf(‘平均绝对误差 (MAE): %.4f\n‘, metrics.MAE); fprintf((平均绝对百分比误差 (MAPE): %.2f%%\n‘, metrics.MAPE); fprintf(‘决定系数 (R²): %.4f\n‘, metrics.R2); fprintf(‘\n‘); end这样组织代码逻辑清晰易于调试和分享。别人拿到你的代码只需要运行主脚本就能复现全部结果。6.2 模型部署生成独立可执行文件或函数如果你需要将模型集成到其他系统或者给不会MATLAB的人使用可以考虑编译。生成函数使用genFunction将网络转换为纯MATLAB代码函数。genFunction(net, ‘myNeuralNetworkFunction‘);这会生成一个myNeuralNetworkFunction.m文件里面包含了网络的所有权重和计算逻辑不依赖神经网络工具箱即可运行只需要基本的MATLAB环境。编译为独立应用需要MATLAB Compiler% 创建一个入口函数例如 deploy_predict.m function result deploy_predict(inputData) load(‘trained_network.mat‘, ‘net‘, ‘ps_input‘, ‘ps_output‘); % 预处理输入数据例如归一化 inputNorm mapminmax(‘apply‘, inputData‘, ps_input)‘; % 预测 outputNorm net(inputNorm‘); % 反归一化 result mapminmax(‘reverse‘, outputNorm, ps_output)‘; end % 在命令行使用mcc编译 % mcc -m deploy_predict.m -a trained_network.mat6.3 数学建模论文中的写作要点最后模型再好也需要在论文中清晰地表达出来。在你的数学建模论文“模型建立与求解”部分关于神经网络模型你需要阐述清楚以下几点模型选择依据为什么选择神经网络而非线性回归、决策树等可以提及数据可能存在复杂非线性关系而神经网络是通用的函数逼近器。网络结构图使用view(net)命令生成结构图插入论文中。清晰地标注输入层、隐藏层含神经元数、输出层。数据预处理细节说明如何处理缺失值、异常值以及为什么进行归一化归一化的区间是多少。数据集划分明确说明训练集、验证集、测试集的比例和划分方法如随机划分并强调验证集用于防止过拟合。训练参数列出关键超参数如隐藏层神经元数、训练算法如Levenberg-Marquardt、学习率、最大迭代次数、早停条件等。评估指标与结果展示测试集上的RMSE、MAPE、R²等指标。务必提供测试集的结果以证明泛化能力。用上文中绘制的预测对比图、误差分布图来直观展示效果。模型对比如果尝试了不同的网络结构或参数可以用表格对比它们的性能并说明最终选择某个模型的理由。模型局限性客观讨论模型的不足例如对数据量的要求、可能存在的过拟合风险、可解释性相对较差等这体现了思考的全面性。记住可执行的代码是基础但能让代码在论文中“讲故事”才是数学建模获奖的关键。从数据到模型从评估到展示形成一个完整、严谨、可复现的逻辑闭环你的工作就具备了强大的说服力。
返回列表