我试图使用 sci-kit learn 的优化器,但遇到了一些我无法解决的问题。我正在尝试使用贝叶斯优化来调整我的 LSTM 深度神经网络的超参数。任何帮助都将非常珍贵。这是我使用的代码。
from skopt.space import Integer, Categorical, Realfrom skopt.utils import use_named_argsfrom skopt import gp_minimizeimport tensorflowimport keras.backend as Kimport GetPredictionimport Modeldim_learning_rate = Real(low=1e-4, high=1e-2, prior='log-uniform', name='learning_rate')dim_num_dense_layers = Integer(low=1, high=5, name='num_dense_layers')dim_num_input_nodes = Integer(low=16, high=128, name='num_input_nodes')dim_num_dense_nodes = Integer(low=8, high=64, name='num_dense_nodes')dim_dropout = Real(low=0.01, high=2, name='dropout')dim_activation = Categorical(categories=['relu', 'sigmoid'], name='activation')dim_batch_size = Integer(low=1, high=128, name='batch_size')dim_adam_decay = Real(low=1e-6, high=1e-2, name="adam_decay")dimensions = [dim_learning_rate, dim_num_dense_layers, dim_num_input_nodes, dim_num_dense_nodes, dim_dropout, dim_activation, dim_batch_size, dim_adam_decay ]default_parameters = [1e-3, 1, 512, 13, 0.5, 'relu', 64, 1e-3]class Optimize: def __init__(self, _STOCK, _INTERVAL, _TYPE): self.stock = _STOCK self.interval = _INTERVAL self._type = _TYPE @use_named_args(dimensions=dimensions) def fitness(self, learning_rate, num_dense_layers, num_input_nodes, num_dense_nodes, dropout, activation, batch_size, rms_decay): model = Model.Tuning_Model(learning_rate=learning_rate, num_dense_layers=num_dense_layers, num_input_nodes=num_input_nodes, num_dense_nodes=num_dense_nodes, dropout=dropout, activation=activation, rms_decay=rms_decay ) Train_Closing, \ Train_Volume, \ Train_Labels, \ Test_Closing, \ Test_Volume, \ Test_Labels, \ ClosingData_scaled, \ VolumeData_scaled = GetPrediction.Return_Data(self.stock, self.interval, self._type) # named blackbox becuase it represents the structure blackbox = model.fit( [ Train_Closing, Train_Volume ], [ Train_Labels ], validation_data=( [ Test_Closing, Test_Volume ], [ Test_Labels ] ), epochs=250, batch_size=batch_size ) # return the validation accuracy for the last epoch. accuracy = blackbox.history['val_mae'][-1] # Delete the Keras model with these hyper-parameters from memory. del model # Clear the Keras session, otherwise it will keep adding new # models to the same TensorFlow graph each time we create # a model with a different set of hyper-parameters. K.clear_session() tensorflow.reset_default_graph() # the optimizer aims for the lowest score, so we return our negative accuracy return -accuracy def Return_BestHyperParameters(self): gp_result = gp_minimize(func=self.fitness, dimensions=dimensions, n_calls=12) return gp_resultif __name__ == '__main__': MyClass = Optimize('DJI', '', 'Daily') print(MyClass.Return_BestHyperParameters())
大部分代码来自我最近阅读的一篇文章。这里是错误信息。
/home/martin/PycharmProjects/MarketPredictor/venv/lib/python3.6/site-packages/sklearn/externals/joblib/__init__.py:15: FutureWarning: sklearn.externals.joblib 在 0.21 版本中已被废弃,将在 0.23 版本中移除。请直接从 joblib 导入此功能,可以通过:pip install joblib 安装。如果此警告是在加载 pickled 模型时触发的,您可能需要使用 scikit-learn 0.21+ 重新序列化这些模型。 warnings.warn(msg, category=FutureWarning)/home/martin/PycharmProjects/MarketPredictor/venv/lib/python3.6/site-packages/sklearn/utils/deprecation.py:144: FutureWarning: sklearn.metrics.scorer 模块在 0.22 版本中已被废弃,将在 0.24 版本中移除。相应的类/函数应改从 sklearn.metrics 导入。任何无法从 sklearn.metrics 导入的内容现在都是私有 API 的一部分。 warnings.warn(message, FutureWarning)使用 TensorFlow 后端。Traceback (most recent call last): File "/home/martin/PycharmProjects/MarketPredictor/Optimizer.py", line 104, in <module> print(MyClass.Return_BestHyperParameters()) File "/home/martin/PycharmProjects/MarketPredictor/Optimizer.py", line 98, in Return_BestHyperParameters n_calls=12) File "/home/martin/PycharmProjects/MarketPredictor/venv/lib/python3.6/site-packages/skopt/optimizer/gp.py", line 237, in gp_minimize n_jobs=n_jobs) File "/home/martin/PycharmProjects/MarketPredictor/venv/lib/python3.6/site-packages/skopt/optimizer/base.py", line 248, in base_minimize next_y = func(next_x)TypeError: wrapper() 需要 1 个位置参数,但提供了 2 个Process finished with exit code 1
提前感谢大家。
回答:
一个最小的可复现示例会很好。但我假设问题在于需要最小化的函数是一个方法。因此 scipy 中的 func 会收到两个参数(self 和 x)。请尝试以下方法:
def Return_BestHyperParameters(self): gp_result = gp_minimize(func=lambda x: self.fitness(x), dimensions=dimensions, n_calls=12) return gp_result
编辑以适应装饰器:
from skopt.space import Integer, Categorical, Realfrom skopt.utils import use_named_argsfrom skopt import gp_minimizeimport tensorflowimport keras.backend as Kimport GetPredictionimport Modeldim_learning_rate = Real(low=1e-4, high=1e-2, prior='log-uniform', name='learning_rate')dim_num_dense_layers = Integer(low=1, high=5, name='num_dense_layers')dim_num_input_nodes = Integer(low=16, high=128, name='num_input_nodes')dim_num_dense_nodes = Integer(low=8, high=64, name='num_dense_nodes')dim_dropout = Real(low=0.01, high=2, name='dropout')dim_activation = Categorical(categories=['relu', 'sigmoid'], name='activation')dim_batch_size = Integer(low=1, high=128, name='batch_size')dim_adam_decay = Real(low=1e-6, high=1e-2, name="adam_decay")dimensions = [dim_learning_rate, dim_num_dense_layers, dim_num_input_nodes, dim_num_dense_nodes, dim_dropout, dim_activation, dim_batch_size, dim_adam_decay ]default_parameters = [1e-3, 1, 512, 13, 0.5, 'relu', 64, 1e-3]def fitness_wrapper(_STOCK, _INTERVALL, _TYPE): @use_named_args(dimensions=dimensions) def fitness(self, learning_rate, num_dense_layers, num_input_nodes, num_dense_nodes, dropout, activation, batch_size, rms_decay): model = Model.Tuning_Model(learning_rate=learning_rate, num_dense_layers=num_dense_layers, num_input_nodes=num_input_nodes, num_dense_nodes=num_dense_nodes, dropout=dropout, activation=activation, rms_decay=rms_decay ) Train_Closing, \ Train_Volume, \ Train_Labels, \ Test_Closing, \ Test_Volume, \ Test_Labels, \ ClosingData_scaled, \ VolumeData_scaled = GetPrediction.Return_Data(self.stock, self.interval, self._type) # named blackbox becuase it represents the structure blackbox = model.fit( [ Train_Closing, Train_Volume ], [ Train_Labels ], validation_data=( [ Test_Closing, Test_Volume ], [ Test_Labels ] ), epochs=250, batch_size=batch_size ) # return the validation accuracy for the last epoch. accuracy = blackbox.history['val_mae'][-1] # Delete the Keras model with these hyper-parameters from memory. del model # Clear the Keras session, otherwise it will keep adding new # models to the same TensorFlow graph each time we create # a model with a different set of hyper-parameters. K.clear_session() tensorflow.reset_default_graph() # the optimizer aims for the lowest score, so we return our negative accuracy return -accuracy return fitnessdef Return_BestHyperParameters(_STOCK, _INTERVALL, _TYPE): gp_result = gp_minimize(func=fitness_wrapper(_STOCK, _INTERVALL, _TYPE), dimensions=dimensions, n_calls=12) return gp_resultif __name__ == '__main__': print(Return_BestHyperParameters(_STOCK="DJI", _INTERVALL="", _TYPE="Daily"))