使用lmfit brute方法报错:TypeError: brute()不识别workers参数
lmfit Brute方法报错:TypeError: brute() got an unexpected keyword argument 'workers'
问题场景
使用lmfit基于scipy minimize的brute-force方法优化含参数a、b、c、d、e的test_fn()函数,代码如下:
def test_fn(param): # example function to be optimised return param['a']+ param['b']+param['c']+param['d'] + param['e'] def brute_wrapper(optimiser_parameters): """ so I can optimise test_fn() across any parameter set """ initial = {'a': 1., 'b': 2., 'c': 3., 'd': 4., 'e': 5.} parameters = optimiser_parameters.valuesdict() for key in initial.keys(): # replace parameters established in optimiser if key in parameters.keys(): initial[key] = parameters[key] return test_fn(initial) # fitness indicator optimisers = lmfit.Parameters() optimisers.add("b", min=1, max=5, brute_step=1) optimisers.add("c", min=2, max=8, brute_step=1) optimisers.add("d", min=1, max=6, brute_step=1) optimisers.add("e", min=5, max=11, brute_step=1) brute = lmfit.minimize(brute_wrapper, optimisers, method='brute')
运行代码时返回如下错误:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-138-70999d7bb08c> in <module>() ---> 12 brute = lmfit.minimize(brute_wrapper, optimisers, method='brute')` ~/.local/lib/python3.6/site-packages/lmfit/minimizer.py in minimize(self, method, params, **kws) 2361 val.lower().startswith(user_method)): 2362 kwargs['method'] = val -> 2363 return function(**kwargs) 2364 2365 ~/.local/lib/python3.6/site-packages/lmfit/minimizer.py in brute(self, params, Ns, keep, workers, max_nfev) 1941 result.call_kws = brute_kws 1942 try: -> 1943 ret = scipy_brute(self.penalty, tuple(ranges), **brute_kws) 1944 except AbortFitException: 1945 pass TypeError: brute() got an unexpected keyword argument 'workers'
手动添加workers=1参数后仍出现相同错误,参考旧帖无此报错,疑问是否为版本更新导致的未文档化变更或Bug?
问题原因
这是scipy与lmfit版本不兼容导致的:
- lmfit的
brute方法会默认向scipy的scipy.optimize.brute传递workers参数,但该参数是scipy 1.5.0版本才新增的并行计算参数。 - 你的环境中scipy版本低于1.5.0,不支持
workers参数,因此触发该错误。手动添加workers=1也没用,因为lmfit还是会把这个参数传给不支持它的旧版scipy。
解决办法
有两种可行方案:
- 方案1:升级scipy版本
执行以下命令将scipy升级到1.5.0及以上版本:pip install --upgrade scipy - 方案2:让lmfit不传递
workers参数
修改lmfit.minimize的调用代码,显式设置workers=None,让lmfit跳过该参数的传递:brute = lmfit.minimize(brute_wrapper, optimisers, method='brute', workers=None)
代码优化建议
你的brute_wrapper函数可以简化,无需循环替换参数,直接用字典合并语法实现参数覆盖:
def brute_wrapper(params): """优化test_fn()的包装函数""" initial = {'a': 1., 'b': 2., 'c': 3., 'd': 4., 'e': 5.} # 用优化器中的参数覆盖初始值 combined_params = {**initial, **params.valuesdict()} return test_fn(combined_params)
内容的提问来源于stack exchange,提问作者user14461441
相关产品推荐
相关产品推荐

