Dlib最近发布了一种全局优化的新方法,最大限度地减少了函数调用的数量(http://blog.dlib.net/2017/12/a-global-optimization-algorithm-worth.html)
我想在Python中使用它,对于一个简单的成本函数,它运行良好:
import dlib
import numpy as np
def cost_fn_2_params(x0, x1):
return np.sum([x0, x1])
dlib.find_max_global(f=cost_fn_2_params, bound1=[-1., -1],
bound2=[1., 1], num_function_calls=10)
现在,在我的特定用例中,我有一个可变数量的参数进入我的成本函数,find_global_max
期望成本函数具有静态数量的参数。例如,以另一种方式定义成本函数:
def cost_fn_unspecified_params(**params):
return np.sum(params)
dlib.find_max_global(f=cost_fn_unspecified_params, bound1=[-1., -1],
bound2=[1., 1], num_function_calls=10)
我收到以下错误:
Failing expression was num == args.size().
The function being optimized takes a number of arguments that doesn't agree with the size of the bounds lists you provided to find_max_global()
我的问题是:有没有办法用一定数量的参数动态定义函数?排除*params
语法,因为这显然只是dlib
的一个参数。
我考虑使用exec
来定义一个函数,但它似乎过于复杂。到目前为止,这是我最好的解决方案:
def get_fn_n_arguments(n):
argument_list = [f'x{ii}' for ii in range(n)]
argument_str = ','.join(argument_list)
def_str = f'def fn({argument_str}): \n\tparams = [{argument_str}]\n\treturn cost_fn_unspecified_params(params)'
print(def_str)
exec(def_str, globals())
这会将函数fn
放入全局命名空间,现在我可以
get_fn_n_arguments(2)
dlib.find_max_global(f=fn, bound1=[-1., -1],
bound2=[1., 1], num_function_calls=10)
它有效,但它似乎是一个非常脆弱的解决方案。我真的想改进它。