ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

MATLAB神经网络与遗传算法组合建模:预测优化实战

MATLAB神经网络与遗传算法组合建模:预测优化实战 在实际工程和科研任务中预测与优化是最常见的两类问题前者希望根据历史数据推测未来的输出后者希望在多个决策变量中找到最优组合。MATLAB 之所以在算法验证和工程仿真中流行除了语法贴近数学表达之外还有一个重要原因它把神经网络、遗传算法等成熟算法封装成了可以直接调用的工具箱。本文不打算只讲概念而是围绕一个完整案例演示如何用 MATLAB 神经网络工具箱完成预测并用全局优化工具箱中的遗传算法优化神经网络初始权重最终实现“预测 优化”的组合建模。同时还会单独演示遗传算法在连续函数优化中的用法方便没有神经网络背景的读者也能快速上手。文章的阅读门槛不高只要你会基本的 MATLAB 矩阵操作和脚本编写就可以跟着一步步执行。读完以后你将掌握 fitnet 创建 BP 神经网络的方法、mapminmax 数据归一化方法、ga 遗传算法函数的使用方法以及如何把遗传算法和神经网络结合起来提升模型的全局搜索能力。内容偏工程实践代码可以直接复制到 MATLAB 中运行我也会在最后给出常见报错排查清单和工程化建议。1. 背景为什么要同时掌握神经网络和遗传算法1.1 预测与优化在工程中的常见场景预测问题的典型形式是给定输入 X希望模型输出 Y。比如根据温度、湿度和风速预测光伏发电功率根据历史负荷预测未来一段时间的用电量根据工艺参数预测材料强度。这类问题的共同点是输入和输出之间存在复杂、非线性的映射关系很难写出显式公式。神经网络正好适合这类场景它通过多层非线性变换学习输入输出之间的映射。优化问题的典型形式是在满足约束条件的前提下找到一组决策变量使某个目标函数最小或最大。比如确定反应釜的温度、压力和催化剂量使产品收率达到最大确定充电桩的功率分配使运营成本最小确定结构件尺寸使重量最小且强度满足要求。这类问题同样存在多个局部极值普通梯度下降方法容易陷入局部最优而遗传算法是一种基于种群搜索的全局优化方法。由此可见神经网络和遗传算法分别攻克的正是“预测”和“优化”两大方向。实际项目里这两者并不是割裂的你可能先用神经网络建立代理模型再在这个模型上做优化也可能用遗传算法为神经网络寻找更好的初始参数。这正是本文要展示的组合思路。1.2 神经网络和遗传算法的互补关系BP 神经网络采用误差反向传播算法本质上是一种梯度下降方法。它对初始权重非常敏感初始值选得不好训练过程可能收敛到较差的局部极小点。遗传算法则不同它模拟生物进化中的选择、交叉和变异依靠群体搜索保留更优的候选解不依赖梯度信息因此具有较强的全局搜索能力。但也正因为遗传算法不依赖梯度它的局部精化能力较弱在最优解附近往往需要大量迭代才能继续提升。神经网络恰好擅长局部精化一旦初始位置较好梯度下降可以高效地把误差降下去。两者的关系可以理解为“先全局搜索再局部精化”先用遗传算法在大范围空间中找到一组较优初始权重再用 BP 训练在这组初始值附近做精细调整。这种“GA BP”的组合在 MATLAB 中实现成本很低核心思路就是获取网络权重向量、编写适应度函数、使用 ga 函数优化、把最优个体写回网络。后面第 5 节会给出完整代码。1.3 本文的实战范围为了让文章更有可操作性我设计了三个层次的案例使用 MATLAB 神经网络工具箱完成 BP 预测使用遗传算法优化 BP 网络初始权重并与普通 BP 对比使用遗传算法求解一个常见的连续函数优化问题。第一个案例解决“预测怎么做”第二个案例解决“神经网络和遗传算法怎么结合”第三个案例单独展示遗传算法的优化能力。通过这三个案例你既能掌握两个工具箱的单独用法也能理解它们协作时的数据流。2. MATLAB 环境准备与工具箱说明2.1 版本与环境检查本文代码使用 MATLAB 编写涉及 Deep Learning Toolbox深度学习工具箱早期版本称为 Neural Network Toolbox和 Global Optimization Toolbox全局优化工具箱。不同 MATLAB 版本在函数默认参数上略有差异但 fitnet、train、ga 等核心函数的调用方式基本一致。建议在命令行执行以下代码确认两个工具箱是否可用disp(ver(deep)); disp(ver(globaloptim));如果输出中包含版本信息说明工具箱已经安装。如果提示找不到对应名称或者输出为空说明当前环境下没有安装对应工具箱需要联系管理员安装或者更换为包含这两个工具箱的 MATLAB 版本。需要注意的是不要直接使用ver判断某个单独的函数是否存在因为某些函数会被其他工具箱依赖建议用which fitnet和which ga辅助确认which fitnet which ga只有两个命令都能正确返回路径后面代码才能顺利执行。2.2 Deep Learning Toolbox 与 Global Optimization ToolboxDeep Learning Toolbox 提供了大量神经网络相关函数。本文用到的 fitnet 是“拟合神经网络”的入口适合回归预测问题。与其功能相似的还有 feedforwardnet两者的区别主要是默认训练算法和部分参数不同fitnet 的默认设置更偏向函数拟合。Global Optimization Toolbox 提供了遗传算法 ga、模拟退火 simulannealbnd、粒子群算法 particleswarm 等求解器。ga 函数的输入参数包括目标函数、变量个数、线性约束、边界条件和优化选项使用方法非常灵活。两个工具箱可以独立使用也可以混合使用。本文的 GA-BP 案例就是把两个工具箱打通的关键示例用 getwb 提取网络权重用 ga 优化这个权重向量再用 setwb 写回网络。这种操作方式在官方文档和工程实践中都有应用。2.3 数据准备说明本文为了演示方便使用仿真数据而非外部数据。仿真函数为y 0.5 * x1^2 1.2 * sin(x2) 0.8 * x3 - 0.3 * x1 * x2 noise其中 x1、x2、x3 是输入变量y 是输出变量noise 是高斯噪声。实际业务中你只需要把 X 和 Y 替换成自己的数据矩阵代码主体不需要大改。3. 核心概念速览3.1 BP 神经网络到底做了什么BP 神经网络是一种多层前馈网络典型结构包含输入层、隐藏层和输出层。输入信号经过每一层的权重线性组合和激活函数非线性变换后得到输出。训练过程先前向计算输出再根据误差反向传播更新每一层权重。隐藏层节点数决定了网络的表达能力。节点太少模型容易欠拟合节点太多模型容易过拟合。本文使用两个隐藏层节点数分别为 10 和 5对于仿真数据来说已经足够。实际应用中隐藏层节点数通常需要通过实验调节。3.2 fitnet 与 train 的工作流程fitnet 创建网络后还需要执行 configure 操作。configure 的作用是根据训练数据初始化输入输出处理参数例如 mapminmax 的缩放参数。如果不调用 configure直接提取权重或计算网络输出可能会因为处理参数未初始化而报错。train 是训练函数它根据训练数据和训练参数更新网络权重。调用方式为net train(net, XTrain, YTrain);train 会返回训练后的网络和训练记录 tr。训练记录中包含训练、验证、测试的损失曲线信息是分析模型状态的重要依据。3.3 遗传算法的三个核心操作遗传算法模拟生物进化过程。首先随机生成一个种群种群中的每个个体都是一组候选解。接下来循环执行三个操作选择根据适应度选出较优个体。适应度越小或越大取决于目标函数定义。交叉把两个个体的一部分编码交换生成新个体。变异对个体的部分编码做随机扰动增加种群多样性。迭代若干代后种群中的个体会逐渐逼近全局最优区域。遗传算法不要求目标函数可导因此非常适合处理神经网络权重优化这类非光滑问题。3.4 ga 函数的调用方式ga 函数的常用调用格式如下[xBest, fBest] ga(ObjectiveFunction, nvars, A, b, Aeq, beq, lb, ub, nonlcon, options);其中ObjectiveFunction 是目标函数句柄nvars 是决策变量个数A、b、Aeq、beq 是线性约束lb、ub 是决策变量下界和上界nonlcon 是非线性约束函数句柄options 是 optimoptions 创建的选项对象。如果不使用线性约束和非线性约束对应位置可以写空数组[]。优化过程中可以通过 optimoptions 设置种群大小、最大迭代代数、显示方式等。3.5 GA 优化神经网络的常见思路遗传算法与神经网络结合并不是只有一种写法常见的有以下几种优化初始权重先使用 ga 搜索较好的初始权重再把权重赋给网络最后用 train 做局部训练完全替代训练把适应度函数定义为验证集误差使用 ga 直接搜索网络权重不再使用 BP 训练优化网络结构把隐藏层节点数、学习率等超参数编码进染色体遗传算法负责搜索超参数组合优化输入特征每个个体表示一个特征子集适应度是模型在特征子集上的预测误差。本文第 5 节主要演示前两种思路的组合先用 GA 搜索较好的初始权重再用 BP 训练进一步精化。4. 用 MATLAB 神经网络工具箱完成预测4.1 准备仿真数据创建一个新的脚本文件命名为bp_predict.m。首先使用 rand 生成 500 个样本其中 400 个用于训练100 个用于测试。为了保证结果可复现先设置随机数种子。%% bp_predict.m rng(42); N 500; x1 rand(N, 1) * 4 - 2; x2 rand(N, 1) * 4 - 2; x3 rand(N, 1) * 4 - 2; y 0.5 * x1.^2 1.2 * sin(x2) 0.8 * x3 - 0.3 * x1 .* x2 0.2 * randn(N, 1); X [x1, x2, x3]; Y y;这里把 x1、x2、x3 按列拼接成 500 行 3 列的矩阵 XY 是 500 行 1 列的输出向量。randn生成的噪声让问题更接近真实数据。4.2 数据归一化与训练测试集划分神经网络训练前通常要进行归一化目的是避免数值差异过大导致梯度异常。使用 mapminmax 将训练输入归一化到 [0,1] 区间同时保存归一化参数之后用相同参数处理测试集。idx randperm(N); trainIdx idx(1:400); testIdx idx(401:end); XTrain X(trainIdx, :); YTrain Y(trainIdx, :); XTest X(testIdx, :); YTest Y(testIdx, :); [XTrainNorm, psX] mapminmax(XTrain, 0, 1); XTrainNorm XTrainNorm; XTestNorm mapminmax(apply, XTest, psX); [YTrainNorm, psY] mapminmax(YTrain, 0, 1); YTrainNorm YTrainNorm; YTestNorm mapminmax(apply, YTest, psY);注意 mapminmax 默认按行处理所以输入矩阵需要转置。后面训练网络时输入也统一使用行向量或列向量需要保持一致。本文统一采用“一行一个样本”的格式因此转置后存入 XTrainNorm。4.3 创建并训练 BP 神经网络fitnet 的第一个参数是隐藏层节点向量。如果网络只有一个隐藏层直接写隐藏节点数例如 10如果有多个隐藏层写成行向量例如 [10, 5]。hiddenSizes [10, 5]; net fitnet(hiddenSizes); net.trainFcn trainlm; net.trainParam.showWindow false; net.trainParam.epochs 300; net configure(net, XTrainNorm, YTrainNorm);将 trainFcn 设置为 trainlm表示使用 Levenberg-Marquardt 算法。该算法收敛速度快适合中小规模数据。如果你的数据量很大训练时内存占用较高可以改用 trainscg 或 trainbr。showWindow 设置为 false可以避免每次训练都弹出神经网络训练窗口适合脚本批量运行。configure 的作用是初始化输入输出处理参数并自动生成初始权重和偏置。训练网络的代码如下[net, tr] train(net, XTrainNorm, YTrainNorm);train 输出的 tr 记录了训练过程中的损失变化。可以绘制训练曲线但本文重点不在这里继续下一步预测。4.4 预测与反归一化训练完成后对测试集进行预测yPredNorm net(XTestNorm); yPred mapminmax(reverse, yPredNorm, psY);网络输出的是归一化后的预测值需要用之前保存的 psY 参数反归一化才能得到与原始数据同一量纲的结果。4.5 模型评估与画图回归预测常用的评估指标有均方误差 MSE、均方根误差 RMSE 和平均绝对误差 MAE。mseValue mean((yPred - YTest).^2); rmseValue sqrt(mseValue); maeValue mean(abs(yPred - YTest)); fprintf(BP 预测结果MSE %.4f, RMSE %.4f, MAE %.4f\n, mseValue, rmseValue, maeValue); figure; plot(YTest, bo-, LineWidth, 1); hold on; plot(yPred, r*-, LineWidth, 1); legend(真实值, BP预测值); xlabel(测试样本编号); ylabel(输出值); title(BP神经网络预测结果); grid on;预期输出是三个评估指标的值和一张拟合曲线图。由于随机种子固定每次运行结果一致。读者可以尝试更换网络结构比如把 hiddenSizes 改成 [20, 10]观察误差变化。5. 用遗传算法优化 BP 初始权重GA-BP5.1 整体流程这一节是本文的核心。整体流程可以拆成六步创建并 configure 一个 BP 网络用 getwb 提取网络的全部权重和偏置组成一个一维向量定义适应度函数把一维向量 setwb 回网络计算训练集预测误差 MSE用 ga 搜索最小 MSE 对应的权重向量创建一个新网络用 setwb 将 GA 最优结果写入网络对新网络执行 train 训练并用测试集评估。流程看起来不复杂但需要注意适应度函数中每一次评估都要重新调用 setwb 并执行一次前向计算因此种群越大、迭代代数越多耗时越长。5.2 为什么使用 getwb 和 setwbgetwb 可以返回网络的所有权重和偏置组成的列向量setwb 的作用相反。对于 BP 网络权重包括输入层到隐藏层的权重、隐藏层之间的权重、隐藏层到输出层的权重以及各层的偏置。手动拼接这些矩阵容易出错getwb 和 setwb 可以避免手动处理维度问题。使用方式如下x0 getwb(net); nvars length(x0);优化完成后net2 setwb(net2, xOpt);这样写的代码更简洁也更不容易出错。如果你的 MATLAB 版本较老建议先输入help getwb确认函数是否存在。5.3 完整可运行的 GA-BP 代码将以下代码保存为runGABP.m然后在命令行执行runGABP。这里采用函数文件而不是脚本文件是为了让嵌套函数能够访问主函数工作区中的网络和训练数据。%% runGABP.m function runGABP %% 数据准备 rng(42); N 500; x1 rand(N, 1) * 4 - 2; x2 rand(N, 1) * 4 - 2; x3 rand(N, 1) * 4 - 2; y 0.5 * x1.^2 1.2 * sin(x2) 0.8 * x3 - 0.3 * x1 .* x2 0.2 * randn(N, 1); X [x1, x2, x3]; Y y; idx randperm(N); trainIdx idx(1:400); testIdx idx(401:end); XTrain X(trainIdx, :); YTrain Y(trainIdx, :); XTest X(testIdx, :); YTest Y(testIdx, :); [XTrainNorm, psX] mapminmax(XTrain, 0, 1); XTrainNorm XTrainNorm; XTestNorm mapminmax(apply, XTest, psX); [YTrainNorm, psY] mapminmax(YTrain, 0, 1); YTrainNorm YTrainNorm; YTestNorm mapminmax(apply, YTest, psY); %% 网络结构 hiddenSizes [10, 5]; %% 1. 训练普通 BP 作为基线 net1 fitnet(hiddenSizes); net1.trainFcn trainlm; net1.trainParam.showWindow false; net1.trainParam.epochs 300; net1 configure(net1, XTrainNorm, YTrainNorm); net1 train(net1, XTrainNorm, YTrainNorm); yPredNorm1 net1(XTestNorm); yPred1 mapminmax(reverse, yPredNorm1, psY); mse1 mean((yPred1 - YTest).^2); fprintf(普通BP MSE %.4f\n, mse1); %% 2. 创建用于 GA 优化的网络并提取权重向量 net0 fitnet(hiddenSizes); net0.trainFcn trainlm; net0.trainParam.showWindow false; net0 configure(net0, XTrainNorm, YTrainNorm); x0 getwb(net0); nvars length(x0); lb -3 * ones(nvars, 1); ub 3 * ones(nvars, 1); %% 3. 调用遗传算法优化初始权重 options optimoptions(ga, ... PopulationSize, 30, ... MaxGenerations, 50, ... Display, iter, ... UseParallel, false); [xOpt, fvalOpt] ga(fitnessFunc, nvars, [], [], [], [], lb, ub, [], options); fprintf(GA优化得到的最优适应度 MSE %.4f\n, fvalOpt); %% 4. 使用 GA 最优权重初始化新网络并继续训练 net2 fitnet(hiddenSizes); net2.trainFcn trainlm; net2.trainParam.showWindow false; net2.trainParam.epochs 300; net2 configure(net2, XTrainNorm, YTrainNorm); net2 setwb(net2, xOpt); net2 train(net2, XTrainNorm, YTrainNorm); yPredNorm2 net2(XTestNorm); yPred2 mapminmax(reverse, yPredNorm2, psY); mse2 mean((yPred2 - YTest).^2); fprintf(GA-BP MSE %.4f\n, mse2); %% 5. 对比绘图 figure; plot(YTest, bo-, LineWidth, 1); hold on; plot(yPred1, r*-, LineWidth, 1); plot(yPred2, g^-, LineWidth, 1); legend(真实值, 普通BP, GA-BP); xlabel(测试样本编号); ylabel(输出值); title(普通BP与GA-BP预测结果对比); grid on; %% 嵌套适应度函数 function mse fitnessFunc(x) netTmp setwb(net0, x); yPredTmp netTmp(XTrainNorm); mse mean((yPredTmp - YTrainNorm).^2); end end5.4 代码执行说明运行后命令行会输出两类信息一是遗传算法的迭代信息包括每一代的适应度值变化二是最终的评估指标。由于神经网络训练本身有一定随机性即使设置了随机数种子GA 优化过程仍然可能因不同版本产生不同结果。你可能会看到 GA-BP 的 MSE 比普通 BP 更低也可能相差不大。这并不代表方法有问题因为本例的仿真数据相对简单BP 已经能找到不错的解。如果你希望更明显地看到 GA 的效果可以尝试以下几种修改减小 net.trainParam.epochs例如设置为 50让 BP 训练不充分这样初始权重的影响会被放大增加网络的隐藏层节点数提高网络复杂度增加局部极小点数量增大 GA 的 PopulationSize 和 MaxGenerations让 GA 搜索更充分多次运行脚本观察不同随机种子下两种方法的表现。5.5 从 MSE 看组合优化的意义普通 BP 是从随机初始权重开始训练GA-BP 是从 GA 搜索到的一组较优权重开始训练。后者在理论上更容易避开较差的局部极小点但并不能保证每次都一定优于前者。工程上更合理的做法是把 GA 当作“初始化增强”工具而不是“一定会打败 BP”的银弹。6. 用遗传算法解决连续函数优化问题6.1 问题描述Rastrigin 函数最小化Rastrigin 函数是优化算法测试中常用的多峰函数表达式为f(x) sum(x_i^2 - 10*cos(2*pi*x_i) 10)该函数在 x_i 接近 0 时取得全局最小值 0但在搜索空间内存在大量局部极小点非常考验算法的全局搜索能力。这里使用二维 Rastrigin 函数搜索范围取 [-5.12, 5.12]。6.2 目标函数与求解代码创建脚本文件ga_optimize.m内容如下%% ga_optimize.m rastrigin (x) sum(x.^2 - 10 * cos(2 * pi * x) 10); nvars 2; lb [-5.12, -5.12]; ub [5.12, 5.12]; options optimoptions(ga, ... PopulationSize, 100, ... MaxGenerations, 200, ... Display, final, ... PlotFcn, gaplotbestf); [xBest, fBest] ga(rastrigin, nvars, [], [], [], [], lb, ub, [], options); fprintf(最优解x1 %.6f, x2 %.6f\n, xBest(1), xBest(2)); fprintf(最优目标值f %.6f\n, fBest);这个脚本使用匿名函数作为目标函数ga 会在每一代中调用它计算种群中个体的适应度。gaplotbestf 是 MATLAB 内置绘图函数用来绘制每代最优适应度变化曲线。6.3 运行结果与参数调节思路二维 Rastrigin 函数的全局最优值接近 0因此正常运行时 fBest 应该很小。由于遗传算法是随机算法每次运行结果可能略有不同但理论上都能收敛到接近全局最优的位置。如果你想继续探索可以修改 nvars 为 5 或 10将搜索维度提高到高维也可以把 PopulationSize 调到 200、MaxGenerations 调到 500观察收敛精度变化。遗传算法的参数没有万能组合需要根据问题规模和目标函数形态反复实验。7. 常见问题与排查思路问题现象常见原因解决思路提示 Undefined function or variable fitnet未安装 Deep Learning Toolbox或 MATLAB 路径异常在命令行输入 ver(deep) 检查工具箱输入 which fitnet 查看路径提示 Undefined function or variable ga未安装 Global Optimization Toolbox安装工具箱或更换 MATLAB 版本输入 ver(globaloptim) 确认configure 报错输入输出维度与网络结构不匹配检查 XTrainNorm 和 YTrainNorm 的行列数确保网络期望维度一致trainlm 训练时内存不足样本量太大或隐藏层节点过多改用 trainscg 或减小网络规模对大样本采用分批训练GA 收敛很慢变量维度过高、边界过大或种群太小缩小 lb 和 ub 边界增加 PopulationSize 和 MaxGenerationssetwb 后网络输出异常优化权重向量与 getwb 长度不一致或没有先 configure用 length(getwb(net)) 检查长度确保 configure 已经执行GA-BP 和普通 BP 结果接近数据太简单或 BP 本身已经收敛到较好位置增加网络复杂度调小训练迭代次数多次运行观察差异每次运行结果不同遗传算法和神经网络训练都包含随机性使用 rng 固定随机数种子或多运行几次取最优排查时建议从最简单的问题入手先确认工具箱是否可用再确认数据矩阵维度最后检查网络配置和遗传算法参数。代码报错信息通常已经给出了出错位置结合命令行堆栈可以快速定位。8. 工程化建议与最佳实践在实际项目里使用 MATLAB 工具箱完成神经网络和遗传算法建模时可以遵循以下几条建议数据清洗优先。神经网络对数据质量非常敏感训练前需要检查缺失值、异常值和重复样本。本文示例用的是仿真数据所以省略了清洗步骤但真实业务中这一步不能省。归一化参数要复用。训练集和测试集必须使用同一套归一化参数如果单独对测试集做一次 mapminmax会导致数据分布不一致评估结果失真。适应度函数要轻量。在 GA 优化网络中适应度函数会被调用成千上万次每次都应该避免写文件、打开 GUI、打印大量日志。如果适应度计算太慢可以先减少训练样本量或简化网络结构验证流程正确后再扩大规模。随机种子和多次运行。算法验证阶段可以用 rng 固定随机种子保证实验结果可复现正式报告结果时建议同一个参数设置多次运行记录均值、方差和中位数而不是只看单次结果。边界条件要合理。遗传算法中 lb 和 ub 的设置会影响搜索效率。如果权重边界设置过大搜索空间太大收敛慢如果设置过小最优权重可能落在边界外。初始权重通常较小所以本文取 [-3, 3]实际项目中可以结合 getwb 的初始值范围调整。注意过拟合。神经网络模型在训练集上表现好不代表测试集上表现好。建议把训练集再拆出一部分作为验证集或者使用早停机制train 默认会使用一部分样本作为验证集并在测试集上做最终评估。模块化组织代码。把数据准备、模型训练、优化求解尽量拆成不同函数或脚本。这样后续替换数据、更换网络结构或修改优化参数时不需要改动其他部分。9. 总结与下一步本文从预测和优化两个角度切入分别演示了 MATLAB 神经网络工具箱和全局优化工具箱的典型用法。第 4 节完成了 BP 神经网络的预测流程第 5 节把遗传算法和神经网络结合起来通过 getwb、setwb、ga 三个函数完成了 GA-BP 组合建模第 6 节又单独展示了遗传算法在连续函数优化中的应用。这样安排的意义在于先熟悉单个工具箱再理解两个工具箱如何协作最后回到纯优化问题巩固对 ga 函数参数的认识。下一步你可以尝试把仿真数据换成真实业务数据例如历史负荷数据、工艺参数数据或设备运行数据。也可以把 BP 网络换成其他神经网络结构比如用 lstm 处理时间序列用卷积神经网络处理图像输入。优化算法方面除了遗传算法MATLAB 还提供粒子群算法 particleswarm 和模拟退火算法 simulannealbnd都可以与神经网络结合。真正掌握这套方法不是把代码复制运行一遍就结束而是理解每个函数的作用再根据自己的问题修改数据生成部分、网络结构和目标函数。建议你准备一份自己的小数据集从 BP 预测开始逐步加入 GA 优化再扩展到其他优化算法。动手跑通之后你会发现 MATLAB 工具箱把很多复杂的建模细节封装得很好真正需要你思考的核心始终是数据和业务问题本身。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进