所以你已经有了训练好的模型,我们可以将其视为f(x) = y。
将这种情况最小化的标准 SciPy 方法适当地命名为 scipy.optimize.minimize。
要使用它,您只需调整 f(x) = y 函数以适应 SciPy 使用的 API。也就是说,第一个函数参数是要优化的params 列表。第二个参数是可选的,可以包含为整个优化(即您的训练模型)固定的任何args。
def score_trained_model(params, args):
# Get the model from the fixed args.
model = args[0]
# Run the model on the params, return the output.
return model_predict(model, params)
有了这个,再加上一个初步的猜测,你现在可以使用minimize函数了:
# Nelder-Mead is my go-to to start with.
# But it doesn't take advantage of the gradient.
# Something that does, e.g. BGFS, may perform better for your case.
method = 'Nelder-Mead'
# All zeros is fine, but improving this initial guess can help.
guess_params = [0]*14
# Given a trained model, optimize the inputs to minimize the output.
optim_params = scipy.optimize.minimize(
score_trained_model,
guess_params,
args=(trained_model,),
method=method,
)
可以为某些优化方法提供约束和界限。对于不支持的 Nelder-Mead,但您可以在违反约束时返回一个非常大的错误。
旧答案。
OP 希望优化输入 x,而不是超参数。
听起来你想做超参数优化。我选择的 Python 库是 hyperopt: https://github.com/hyperopt/hyperopt
假设您已经有一些训练和评分代码,例如:
def train_and_score(args):
# Unpack args and train your model.
model = make_model(**args)
trained = train_model(model, **args)
# Return the output you want to minimize.
return score_model(trained)
您可以轻松地使用hyperopt 调整学习率、dropout 或激活选择等参数:
from hyperopt import fmin, hp, tpe, space_eval
space = {
'lr': hp.loguniform('lr', np.log(0.01), np.log(0.5)),
'dropout': hp.uniform('dropout', 0, 1),
'activation': hp.choice('activation', ['relu', 'sigmoid']),
}
# Minimize the training score over the space.
trials = Trials()
best = fmin(train_and_score, space, trials=trials, algo=tpe.suggest, max_evals=100)
# Print details about the best results and hyperparameters.
print(best)
print(space_eval(space, best))
还有一些库可以帮助您直接将其与 Keras 集成。一个流行的选择是hyperas:https://github.com/maxpumperla/hyperas