ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于GA-BP神经网络的充填料浆强度与成本双目标优化

基于GA-BP神经网络的充填料浆强度与成本双目标优化 简介这份PDF是《黄金科学技术》2019年第27卷第4期的一篇研究论文面向采矿工程、矿业经济及机器学习建模方向的研究者与工程技术人员聚焦充填法开采中如何在满足充填体抗压强度要求的前提下降低料浆成本。作者以水泥、粉煤灰、尾砂质量分数为输入、抗压强度为输出构建3-9-1的BP神经网络并用遗传算法优化权值与阈值得到预测精度更高的GA_BP模型再将其与成本函数共同作为适应度函数借助带精英策略的非支配排序遗传算法完成多目标寻优。文中呈现样本归一化、隐含层节点试凑与相对平均误差评价等建模细节并给出抗压强度1.5 MPa时成本最低最优配比为水泥8%、粉煤灰2.3%、尾砂66.3%最低成本29.3元/t。压缩包仅含1个PDF约2.29MB已有129人学习适合复现建模流程或指导配比设计时参考。1. 为什么单目标优化在充填料浆配比上会失效矿山充填配比的现场决策通常是这样发生的试验室做二十几组配比试验测出各自的抗压强度然后挑一组强度达标、水泥用量看着最少的方案上现场。这套做法在浅部开采时勉强能用到了深部采场地压管理要求充填体抗压强度稳定在 1.5 MPa 以上单靠试凑法就很难同时压住成本和强度两个指标。原因在于充填料浆的抗压强度与水泥、粉煤灰、尾砂三者的质量分数之间是非线性耦合关系水泥多一点强度上去了、成本也上去了粉煤灰替代部分水泥能降本但会拉低早期强度尾砂浓度变化又会同时影响强度和输送性能。只盯着强度做单目标优化本质上是在一个多维曲面上找极值点很容易落到局部最优上成本压不下来反过来只压成本强度又不可控。这篇文献给出的思路是用 BP 神经网络拟合这层非线性关系再用遗传算法去优化网络的初始权值和阈值最后把训练好的网络当作适应度函数之一做强度与成本的双目标寻优。适合做充填配比试验、矿山技术经济指标建模以及想拿这个案例练多目标优化的技术人员。2. BP 神经网络拟合充填料浆配比与抗压强度2.1 输入输出变量的确定与样本构造这套模型的输入是三个配比参数水泥质量分数 ω1、粉煤灰质量分数 ω2、尾砂质量分数 ω3输出只有一个充填体抗压强度。样本来自现场试验共 24 组其中 121 组作训练集2224 组作测试集。这个划分比例看着粗但对 24 组的小样本其实是合理的测试集留三组足以暴露模型的泛化问题又不会把训练集压得太小。真正需要留意的是样本的覆盖范围2224 组测试样本的 ω1 分别在 6.36%、7.09%、3.90%强度跨度从 0.74 到 1.85 MPa覆盖了低强度和高强度两端如果测试样本全挤在中间区间测试结果会虚高。神经网络对输入数据的量纲很敏感直接拿百分比数值进去训尾砂质量分数动辄六十几水泥只有个位数梯度更新会被大数值维度主导收敛又慢又偏。归一化是必做的一步文献用的是极差归一化import numpy as np import pandas as pd # 24 组充填料浆配比试验数据列为 [ω1, ω2, ω3, 抗压强度] data pd.read_csv(filling_slurry_samples.csv) X_raw data[[cement, flyash, tailings]].values y_raw data[strength].values.reshape(-1, 1) def minmax_fit(x): 按列记录极值训练集和测试集必须共用同一组极值 xmin x.min(axis0) xmax x.max(axis0) return xmin, xmax def minmax_transform(x, xmin, xmax): return (x - xmin) / (xmax - xmin) xmin, xmax minmax_fit(X_raw[:21]) # 只用训练集拟合极值 X_train minmax_transform(X_raw[:21], xmin, xmax) X_test minmax_transform(X_raw[21:], xmin, xmax) # 测试集复用训练集极值 ymin, ymax minmax_fit(y_raw[:21]) y_train minmax_transform(y_raw[:21], ymin, ymax)这里的逻辑说明很重要归一化的极值必须只用训练集拟合再把同一组极值套到测试集上。如果图省事对全部 24 组一起求极值测试集的信息就泄露进训练过程了测试误差会偏乐观。极差归一化把每个维度压到 [0,1]和 Sigmoid 类传递函数的值域对齐避免输出饱和。参数上训练集和测试集共用xmin/xmax这一条是硬约束很多人在这一步栽跟头模型离线看着好上线一换数据就崩。2.2 隐含层神经元数量的确定隐含层神经元个数没有解析解文献的做法是先估算范围再试凑。经验公式为n1 √(n m) an 是输入层神经元数 3m 是输出层神经元数 1a 取 [1,10] 之间的常数算出范围大致在 3 到 12 之间。然后在这个区间里逐个建网每个结构训练 10 次取平均相对误差用相对平均误差 MAE 作为评价指标MAE (1/N) · Σ |y_i - y_i| / y_i文献给出的对比结果很直观隐含层从 4 个加到 12 个误差并不是单调递减的网络结构相对误差迭代次数3-4-10.2838153-5-10.2298983-6-10.2238773-8-10.1961913-9-10.1768233-10-10.17911203-11-10.1959943-12-10.2022483-9-1 的误差最小为 0.1768迭代次数也少所以结构定在这里。这张表隐含一个经验小样本下神经元加多了反而会记住噪声误差回升也就是过拟合。误差在 9 个神经元处出现最低点再往上走又抬起来是典型的容量与样本量不匹配的表现。如果换一批样本重做这个最优点未必还在 9所以试凑这一步不能省直接抄 3-9-1 而不验证是本案例最常见的误用。2.3 学习速率与传递函数的参数配置网络结构定下来后剩下一批参数需要用试验定。学习速率是影响最大的一个设小了训练时间成倍拉长设大了输出会在最优值附近震荡甚至发散。文献把学习速率设为 0.1并选用学习率可变的梯度下降算法 traingda。可变学习率的价值在于误差下降顺利时自动加大步长误差震荡时自动回退比固定学习率鲁棒。传递函数方面隐含层用 tansig 即双曲正切 Sigmoid输出层用 purelin 即线性函数。这里的选择是有道理的隐含层需要非线性表达能力来拟合配比与强度的非线性关系所以用 Sigmoid输出层是连续的强度值不能再用 Sigmoid 把输出压到 [0,1] 区间否则大于 1 的强度值根本表示不出来线性输出层保证值域不受限。训练次数设为 1000配合 traingda 的自适应步长通常能在收敛和过训之间取得平衡。在 MATLAB 里对应的配置大致是net newff(trainX, trainY, 9, {tansig,purelin}, traingda); net.trainParam.lr 0.1; % 初始学习速率 net.trainParam.epochs 1000; % 最大训练代数 net.trainParam.goal 1e-4; % 训练目标误差 net.trainParam.show 50; % 每 50 代显示一次进度 net train(net, trainX, trainY);如果用 Python 实现等价结构用 Keras 描述就是一层Dense(9, activationtanh)加一层Dense(1, activationlinear)优化器选带动量的梯度下降并把学习率调到 0.1 量级。逻辑上是一致的结构层数不变变的是隐含层的激活函数和输出层的线性化处理。参数说明里要强调一点学习速率 0.1 是配合归一化后的小数值输入才安全的如果输入没归一化尾砂那一维动辄 0.6 以上的量级0.1 的学习率很可能直接把权值推飞。3. 用遗传算法优化 BP 网络的初始权值与阈值3.1 为什么要先优化权值再谈预测BP 神经网络的初始权值和阈值是随机生成的同一组样本、同一个网络结构跑两次可能得到两个预测精度差别不小的模型。这个不确定性对小样本建模是致命的因为样本量本来就不足以把权值从任意起点都拉到全局最优附近。遗传算法在这里的角色不是替代 BP而是先给 BP 找一个好的起点把待优化的所有权值和阈值编码成一条染色体用遗传算法的选择、交叉、变异操作在参数空间里搜索找到一组使网络误差较小的初始参数再交给 BP 做梯度微调。这样 BP 的收敛更稳最终精度也更高。3.2 染色体编码与待优化参数的数量3-9-1 结构下需要优化的参数总数是输入层到隐含层的权值 3×927 个隐含层阈值 9 个隐含层到输出层的权值 9×19 个输出层阈值 1 个合计 46 个。编码方式用二进制每个参数编成 10 位二进制串一条染色体就是 46×10460 位其中 1270 位是输入到隐含层的权值271360 位是隐含层阈值361450 位是隐含层到输出层权值451460 位是输出层阈值。这段位段划分不是可选项编码时必须严格对应否则解码出来的权值会错位网络结构就乱了。参数类别数量输入层与隐含层连接权值27隐含层阈值9隐含层与输出层连接权值9输出层阈值1遗传算子的配置是选择算子用随机遍历抽样 sus交叉算子用单点交叉、交叉概率 0.7变异概率 0.01种群大小 40最大遗传代数 50。交叉概率 0.7 属于中高水平保证种群有足够的新解产生变异概率 0.01 偏低作用是维持多样性而不破坏已经收敛的良好基因。适应度函数定义为实际输出与期望输出之差的倒数F 1 / |Y1 - Y2|误差越小适应度越大符合优胜劣汰的方向。在 MATLAB 全局优化工具箱里这套染色体编码一般不用手写用ga的PopulationSize、CrossoverFraction、MutationFcn等参数就能配置但如果要把权值矩阵的解码逻辑嵌进适应度函数还是得自己写映射把 460 位基因串切回四个参数矩阵。3.3 GA_BP 与原始 BP 的精度对比训练过程中遗传算法迭代到 50 代时误差收敛到 0.017242。用测试集 2224 组验证预测精度结果差距很大试验序号期望输出GA_BP 输出GA_BP 相对误差BP 输出BP 相对误差220.900.90050.05%0.96116.79%231.851.84920.08%1.74925.45%240.740.73970.04%0.78245.73%GA_BP 的平均相对误差约 0.05%未优化的 BP 约 6%差了两个数量级。这里要冷静看待这个数字单看测试集只有三组0.05% 的误差有点过于漂亮样本量小的时候测试误差本身就带偶然性。更稳的验证做法是保留更多组数据做交叉验证或者至少换个随机种子重复几次看误差的波动区间。文献这个结果的价值在于证实了优化初始权值这个方向是对的而不是说 0.05% 就是个可以复现的固定值。4. 强度与成本的双目标遗传算法寻优4.1 目标函数与约束条件的构建多目标寻优要同时管两个函数。第一个是成本函数把四种组分的单价乘上各自的质量分数再求和f1(ω1, ω2, ω3) ω1×340 ω2×70 ω3×1 (1 - ω1 - ω2 - ω3)×0.8水泥 340 元/t、粉煤灰 70 元/t、尾砂运价 1 元/t、水 0.8 元/t系数直接来自现场单价。第二个是强度函数直接用训练好的 GA_BP 网络做前向推理f2(ω1, ω2, ω3) sim(net, [ω1; ω2; ω3])MATLAB 的遗传算法默认求最小值成本函数本来就是求最小方向对强度函数是求最大所以要取负号改成-sim(net, ...)两个目标才能在同一套求解框架里跑。约束条件是抗压强度不低于 1.5 MPa配比参数的取值范围是 ω1 在 2%16%ω2 在 0%20%ω3 在 50%75%。这三条边界不能随手放宽尾砂质量分数低于 50% 时料浆的输送特性会出问题水泥质量分数给太大则成本失控边界的设定本身就是工程约束的体现。全局遗传算子的参数和前一阶段不一样最优前端个体系数 0.3种群大小放大到 1000最大进化代数 200停止代数 200适应度函数值偏差 1×10⁻³。种群规模从 40 提到 1000 是因为多目标问题要维持 Pareto 前沿的分布性个体太少前沿会稀疏取不到中间强度段的最优解。4.2 最优配比结果与成本核算迭代 200 次后得到每个强度等级下的最低成本和对应配比。摘几档关键的抗压强度ω1ω2ω3最低成本/(元·t⁻¹)1.2 MPa7.02.567.226.21.4 MPa7.62.967.528.51.5 MPa8.02.366.829.31.6 MPa6.89.266.330.42.0 MPa7.112.569.033.5验算 1.5 MPa 那一档8%×340 2.3%×70 66.8%×1 (1-8%-2.3%-66.8%)×0.8 ≈ 29.3 元/t和优化输出一致。对照文献里的试验数据水泥 8.2%、粉煤灰 0.4%、尾砂 65.78% 时实测强度 1.54 MPa与模型给出的 8.0%、2.3%、66.8% 在强度和配比上都接近说明模型的推理落到了实际可行的区域里不是凭空生成的数学解。这个对照很重要优化结果如果只满足数学最优而不符合现场经验那模型就是失败的。5. 复现这套模型时最容易踩的坑第一个坑是归一化极值泄露。前面提过一次这里展开说无论用 Python 还是 MATLAB都要把极值计算封装成单独一步只对训练集调用测试集一律复用。用 sklearn 的话MinMaxScaler的fit只喂训练集transform才作用于测试集写成fit_transform(X_all)就错了。第二个坑是遗传算法的早熟收敛。多目标寻优阶段种群规模已经设到 1000如果发现 Pareto 前沿很快就挤成一堆、解集多样性崩掉先检查变异概率是不是太低其次是种群规模。小种群配低变异概率几十代内就会收敛到局部前沿。判断方法很简单把适应度函数值偏差的停止阈值调小看算法还能不能继续改善改善不动了基本就是早熟。第三个坑也是最要命的一个模型预测的精度决定了最终配比的可靠性但 GA_BP 在小样本上的高精度未必稳定。建议用留一法交叉验证替换掉三组固定测试集from sklearn.model_selection import LeaveOneOut from sklearn.neural_network import MLPRegressor import numpy as np loo LeaveOneOut() errors [] for train_idx, test_idx in loo.split(X_raw): xmin, xmax X_raw[train_idx].min(0), X_raw[train_idx].max(0) Xtr (X_raw[train_idx] - xmin) / (xmax - xmin) Xte (X_raw[test_idx] - xmin) / (xmax - xmin) # 每个折都重新优化权值再训练避免信息泄露 model MLPRegressor(hidden_layer_sizes(9,), activationtanh, solversgd, learning_rate_init0.1, max_iter1000) model.fit(Xtr, y_raw[train_idx]) pred model.predict(Xte) errors.append(abs(pred[0] - y_raw[test_idx][0]) / y_raw[test_idx][0]) print(f留一法平均相对误差: {np.mean(errors):.4f})留一法的每一折都用不同的训练子集重新拟合极值能真实反映模型在没见过数据上的表现。如果留一法误差远高于固定测试集的 0.05%说明原来的结果有测试集挑选的成分最终配比要以留一法误差为准来评估风险。最后一个技巧是给优化结果加一道现场校验拿模型给出的配比做一组小试实测强度和成本对不上就回头修正样本集或网络结构。数学模型给出的是搜索方向真正落地还得靠试验锚定这条经验在矿山配比这类强工程约束的场景里比任何一个参数调优都管用。本文还有配套的精品资源点击获取
返回列表