Python中Scipy优化的多进程实现问题求助
问题1:多进程运行报错的解决
错误原因
pool.map传参错误:map会将arguments元组的每个元素(100、1、2、3)分别作为单个参数传给fit,但fit需要两个参数(目标函数func和参数元组arguments),导致参数不匹配,同时触发pickle反序列化错误。- Windows spawn机制的序列化问题:Windows下多进程采用spawn模式,子进程会重新导入主模块,传参错误加剧了序列化失败。
修正后的多进程代码
from scipy import optimize import multiprocessing as mp # 待最小化的函数 def func(x, arg1, arg2, arg3): return x*x + arg1*x + arg2*x + arg3*x # 封装优化逻辑的函数 def fit(func, arguments): x0, arg1, arg2, arg3 = arguments results = optimize.minimize(func, x0, args=(arg1, arg2, arg3), method='BFGS') print(f'函数最小值: {results.fun}') print(f'最小值对应的参数x: {results.x}') return results # 主程序 if __name__ == "__main__": # 参数初始化 x0=100 arg1=1 arg2=2 arg3=3 arguments=(x0, arg1, arg2, arg3) # 多进程修正:使用starmap,传入包含参数元组的可迭代对象 with mp.Pool(mp.cpu_count()) as pool: # 把func和arguments打包成一个元组,放在列表中(starmap需要可迭代的参数元组集合) pool.starmap(fit, [(func, arguments)])
关键修正点
- 使用
pool.starmap替代pool.map:starmap支持将可迭代对象中的每个元组元素作为位置参数传给目标函数,完美匹配fit需要两个参数的需求。 - 确保参数格式正确:将
func和arguments打包成单个元组,放入列表中作为starmap的输入,保证每个子进程能拿到完整的参数集合。
问题2:优化迭代过程的进度查看
实现方式:使用optimize.minimize的callback参数
scipy.optimize.minimize支持通过callback参数传入自定义函数,每次迭代时会自动调用该函数并传入当前的参数x。该方式完全适用于MLE估计问题(本质上MLE就是最小化负对数似然,和普通优化迭代逻辑一致)。
带回调的完整代码
from scipy import optimize import multiprocessing as mp # 待最小化的函数 def func(x, arg1, arg2, arg3): return x*x + arg1*x + arg2*x + arg3*x # 封装优化逻辑的函数 def fit(func, arguments): x0, arg1, arg2, arg3 = arguments iter_count = 0 # 定义回调函数,通过闭包直接访问当前参数 def callback(x): nonlocal iter_count iter_count +=1 current_fun = func(x, arg1, arg2, arg3) print(f'第{iter_count}次迭代 | 参数x: {x} | 函数值: {current_fun}') results = optimize.minimize(func, x0, args=(arg1, arg2, arg3), method='BFGS', callback=callback) print(f'\n最终函数最小值: {results.fun}') print(f'最终最小值对应的参数x: {results.x}') return results # 主程序 if __name__ == "__main__": # 参数初始化 x0=100 arg1=1 arg2=2 arg3=3 arguments=(x0, arg1, arg2, arg3) # 多进程运行 with mp.Pool(mp.cpu_count()) as pool: pool.starmap(fit, [(func, arguments)])
回调函数说明
- 闭包设计:将回调函数定义在
fit内部,通过闭包直接访问arg1、arg2、arg3,避免使用全局变量,代码更简洁安全。 - 迭代统计:加入
iter_count变量记录迭代次数,方便直观查看优化进度。
内容的提问来源于stack exchange,提问作者Jessica F.
相关产品推荐
相关产品推荐

