使用scipy.optimize.minimize做函数极小化时报内存错误如何解决
问题分析与修正方案
实现错误与报错原因
- 维度适配错误:
scipy.optimize.minimize要求传入的初始值x0为1维数组,你传入的h_in是3维结构,即使函数内部自动展平,你定义的lambda函数用h[0]、h[1]索引也完全无法匹配展平后的1维参数结构,目标函数本身逻辑就不成立。 - 内存溢出根因:你当前的优化变量总维度为
2*12458*7=174412维,scipy.optimize.minimize默认算法会通过有限差分法自动计算海森矩阵,海森矩阵维度为n×n,17万维参数对应的海森矩阵大小刚好为227GiB,直接超出内存上限。 - 问题定义缺陷:你当前写的目标函数
(h_u * h_v).mean()无下界,只要h_u和h_v对应元素符号相反、绝对值无限增大,函数值就会无限减小,不存在可收敛的最小值,说明你漏写了必要的正则项或约束条件。
修复方案
方案1:适配scipy的优化逻辑(仅适合补充约束后维度不继续扩大的场景)
首先修正参数处理逻辑和目标函数,同时指定仅存储有限历史梯度的L-BFGS-B算法,避免计算全量海森矩阵:
import numpy as np from scipy.optimize import minimize # 示例初始矩阵 h_u = np.random.rand(12458,7) h_v = np.random.rand(12458,7) # 初始值展平为1维 x0 = np.concatenate([h_u.flatten(), h_v.flatten()]) def target_fun(x): # 拆分恢复为两个原始矩阵 h_u_opt = x[:12458*7].reshape(12458,7) h_v_opt = x[12458*7:].reshape(12458,7) # 此处补充你缺失的正则项/约束损失,保证函数有下界 return (h_u_opt * h_v_opt).mean() # 需自行实现梯度计算函数传入jac参数,避免自动有限差分的开销 # 注意:17万维参数用scipy优化速度极慢,仅做原理演示,更推荐方案2 res = minimize(target_fun, x0=x0, method='L-BFGS-B', jac=None)
方案2:改用深度学习框架优化(推荐,适配高维参数场景)
用PyTorch/TensorFlow的自动微分+梯度下降类优化器求解,完全不会触发海森矩阵的内存开销,效率更高:
import torch # 初始化可训练参数 h_u = torch.randn(12458,7, requires_grad=True) h_v = torch.randn(12458,7, requires_grad=True) optimizer = torch.optim.Adam([h_u, h_v], lr=1e-3) # 迭代优化 for step in range(1000): optimizer.zero_grad() # 补充完整损失项 loss = (h_u * h_v).mean() loss.backward() optimizer.step() if step % 100 == 0: print(f"Step {step}, Loss: {loss.item()}")
内容的提问来源于stack exchange,提问作者Python
相关产品推荐
相关产品推荐

