Python sklearn和n_作业中的超参数优化>;1:酸洗
我陷入了困境。以下是我的代码结构:Python sklearn和n_作业中的超参数优化>;1:酸洗,python,scikit-learn,multiprocessing,pickle,keras,Python,Scikit Learn,Multiprocessing,Pickle,Keras,我陷入了困境。以下是我的代码结构: 类似于抽象类的基类 可以实例化的子类 一种设置参数并使用n_jobs=-1调用RandomizedSearchCV或GridSearchCV的方法。 一个局部函数,create\u model,用于创建神经网络模型(参见教程),由KerasClassifier或KerasRegressor 我得到一个错误,说本地对象不能被pickle。如果我更改了n_jobs=1,则没有问题。所以我怀疑问题在于本地函数和并行处理。这有解决办法吗?在谷歌搜索了一下之
- 类似于抽象类的基类
- 可以实例化的子类
- 一种设置参数并使用
调用n_jobs=-1
或RandomizedSearchCV
的方法。GridSearchCV
- 一个局部函数,
,用于创建神经网络模型(参见教程),由create\u model
或KerasClassifier
KerasRegressor
- 一个局部函数,
- 一种设置参数并使用
n_jobs=1
,则没有问题。所以我怀疑问题在于本地函数和并行处理。这有解决办法吗?在谷歌搜索了一下之后,似乎序列化程序dill
可以在这里工作(我甚至在dill上找到了一个名为multiprocessing\u的包)。但我目前依赖于sklearn的软件包。我找到了解决问题的“解决方案”。我真的很困惑,为什么示例可以与n_jobs=-1
一起工作,而我的代码却不能。问题似乎在于驻留在子类方法中的本地函数create\u model
。如果我将局部函数作为子类的一种方法,我就能够设置n_jobs>1
总而言之,下面是我的代码结构:
- 类似于抽象类的基类
- 可以实例化的子类
- 一种设置参数并使用
n_jobs=-1
调用RandomizedSearchCV
或GridSearchCV
的方法
- 一种方法,
创建_模型
,该方法创建神经网络模型,由KerasClassifier
或KerasRegressionor
守则的一般构思:
from abc import ABCMeta
import numpy as np
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
class MLAlgorithms(metaclass=ABCMeta):
def __init__(self, X_train, y_train, X_test, y_test=None):
"""
Constructor with train and test data.
:param X_train: Train descriptor data
:param y_train: Train observed data
:param X_test: Test descriptor data
:param y_test: Test observed data
"""
...
@abstractmethod
def setmlalg(self, mlalg):
"""
Sets a machine learning algorithm.
:param mlalg: Dictionary of the machine learning algorithm.
"""
pass
@abstractmethod
def fitmlalg(self, mlalg, rid=None):
"""
Fits a machine learning algorithm.
:param mlalg: Machine learning algorithm
"""
pass
class MLClassification(MLAlgorithms):
"""
Main class for classification machine learning algorithms.
"""
def setmlalg(self, mlalg):
"""
Sets a classification machine learning algorithm.
:param mlalg: Dictionary of the classification machine learning algorithm.
"""
...
def fitmlalg(self, mlalg):
"""
Fits a classification machine learning algorithm.
:param mlalg: Classification machine learning algorithm
"""
...
# Function to create model, required for KerasClassifier
def create_model(self, n_layers=1, units=10, input_dim=10, output_dim=1,
optimizer="rmsprop", loss="binary_crossentropy",
kernel_initializer="glorot_uniform", activation="sigmoid",
kernel_regularizer="l2", kernel_regularizer_weight=0.01,
lr=0.01, momentum=0.0, decay=0.0, nesterov=False, rho=0.9, epsilon=1E-8,
beta_1=0.9, beta_2=0.999, schedule_decay=0.004):
from keras.models import Sequential
from keras.layers import Dense
from keras import regularizers, optimizers
# Create model
if kernel_regularizer.lower() == "l1":
kernel_regularizer = regularizers.l1(l=kernel_regularizer_weight)
elif kernel_regularizer.lower() == "l2":
kernel_regularizer = regularizers.l2(l=kernel_regularizer_weight)
elif kernel_regularizer.lower() == "l1_l2":
kernel_regularizer = regularizers.l1_l2(l1=kernel_regularizer_weight, l2=kernel_regularizer_weight)
else:
print("Warning: Kernel regularizer {0} not supported. Using default 'l2' regularizer.".format(
kernel_regularizer))
kernel_regularizer = regularizers.l2(l=kernel_regularizer_weight)
if optimizer.lower() == "sgd":
optimizer = optimizers.sgd(lr=lr, momentum=momentum, decay=decay, nesterov=nesterov)
elif optimizer.lower() == "rmsprop":
optimizer = optimizers.rmsprop(lr=lr, rho=rho, epsilon=epsilon, decay=decay)
elif optimizer.lower() == "adagrad":
optimizer = optimizers.adagrad(lr=lr, epsilon=epsilon, decay=decay)
elif optimizer.lower() == "adadelta":
optimizer = optimizers.adadelta(lr=lr, rho=rho, epsilon=epsilon, decay=decay)
elif optimizer.lower() == "adam":
optimizer = optimizers.adam(lr=lr, beta_1=beta_1, beta_2=beta_2, epsilon=epsilon, decay=decay)
elif optimizer.lower() == "adamax":
optimizer = optimizers.adamax(lr=lr, beta_1=beta_1, beta_2=beta_2, epsilon=epsilon, decay=decay)
elif optimizer.lower() == "nadam":
optimizer = optimizers.nadam(lr=lr, beta_1=beta_1, beta_2=beta_2, epsilon=epsilon,
schedule_decay=schedule_decay)
else:
print("Warning: Optimizer {0} not supported. Using default 'sgd' optimizer.".format(optimizer))
optimizer = "sgd"
model = Sequential()
model.add(
Dense(units=units, input_dim=input_dim,
kernel_initializer=kernel_initializer, activation=activation,
kernel_regularizer=kernel_regularizer))
for layer_count in range(n_layers - 1):
model.add(
Dense(units=units, kernel_initializer=kernel_initializer, activation=activation,
kernel_regularizer=kernel_regularizer))
model.add(Dense(units=output_dim,
kernel_initializer=kernel_initializer, activation=activation,
kernel_regularizer=kernel_regularizer))
# Compile model
model.compile(loss=loss, optimizer=optimizer, metrics=['accuracy'])
return model
class MLRegression(MLAlgorithms):
"""
Main class for regression machine learning algorithms.
"""
...
在jupyter笔记本/ipython(Unix上没有问题)的Windows上,在kerasClassifier模型上运行sklearn的网格搜索时,我可以确认同样的问题
我通过将导致pickle问题的create_model函数放入一个模块并导入该模块,而不是在环境中定义该函数,从而解决了这个问题
要为Python创建一个简单的模块
- 在运行主代码的同一文件夹中创建一个文本文件,并将其另存为my_module.py
- 将create_model函数的定义放入文件中
- 不要在代码中定义create\u model,而是使用
import my\u module
导入模块,并使用my\u module.create\u model()
您可以monkeypatch joblib并使其在dill上运行。但这不是一个理想的解决方案。是的,我更感兴趣的是一个不需要像那样修补别人代码的解决方案…:/您使用哪种后端
?@MarcinMożejko:ForKeras
?我想试试TensorFlow和Theano。它会影响错误吗?对于Theano
来说,不可能并行运行模型培训/评估。我对这个问题非常感兴趣,但我似乎无法理解您的代码是如何组织的。你有抽象类的例子吗?我用部分代码更新了我的答案。希望有帮助!谢谢你,伙计!真的很感激!