You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Scipy优化的多进程实现问题求助

问题1:多进程运行报错的解决

错误原因

  1. pool.map传参错误:map会将arguments元组的每个元素(100、1、2、3)分别作为单个参数传给fit,但fit需要两个参数(目标函数func和参数元组arguments),导致参数不匹配,同时触发pickle反序列化错误。
  2. 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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:57:17