Keras KerasClassifier gridsearch TypeError: can't pickle _thread.lock objects

Posted

技术标签:

【中文标题】Keras KerasClassifier gridsearch TypeError: can\'t pickle _thread.lock objects【英文标题】:Keras KerasClassifier gridsearch TypeError: can't pickle _thread.lock objectsKeras KerasClassifier gridsearch TypeError: can't pickle _thread.lock objects 【发布时间】:2018-07-20 21:50:08 【问题描述】:

以下代码抛出错误: TypeError: can't pickle _thread.lock objects

我可以看到它可能与将前一个方法作为函数传递给 def fit(self, c_m) 有关。但我认为通过文档这是正确的:https://keras.io/scikit-learn-api/

如果有人在我的代码中看到错误,我可能会犯一个新手错误,我将不胜感激。

np.random.seed(7)
y_dic = []

class NN:
    def __init__(self):
        self.X = None
        self.y = None
        self.model = None

    def clean_data(self):
        seed = 7
        np.random.seed(seed)
        dataset = pd.read_csv('/Users/isaac/pca_rfe_tsne_comparisons/Vital_intrusions.csv', delimiter=',', skiprows=0)
        dataset = dataset.iloc[:,1:6]
        self.X = dataset.iloc[:, 1:5]
        Y = dataset.iloc[:, 0]

        for y in Y:
            if y >= 8:
                y_dic.append(1)
            else:
                y_dic.append(0)
        self.y = y_dic

        self.X = np.asmatrix(stats.zscore(self.X, axis=0, ddof=1))
        self.y = to_categorical(self.y)


    def create_model(self):
        self.model = Sequential()
        self.model.add(Dense(4, input_dim=4, activation='relu'))
        self.model.add(Dense(4, activation='relu'))
        self.model.add(Dense(2, activation='sigmoid'))
        self.model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
        pass

    def fit(self, c_m):
        model = KerasClassifier(build_fn=c_m, verbose=0)
        batch_size = [10, 20, 40, 60, 80, 100]
        epochs = [10, 50, 100]
        param_grid = dict(batch_size=batch_size, epochs=epochs)
        grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
        pdb.set_trace()
        grid_result = grid.fit(self.X, self.y)
        return (grid_result)

    def results(self, grid_results):
        print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
        means = grid_result.cv_results_['mean_test_score']
        stds = grid_result.cv_results_['std_test_score']
        params = grid_result.cv_results_['params']
        for mean, stdev, param in zip(means, stds, params):
            print("%f (%f) with: %r" % (mean, stdev, param))


def main():
    nn = NN()
    nn.clean_data()
    nn.create_model()
    grid_results = nn.fit(nn.create_model)
    nn.results(grid_results)

if __name__ == "__main__":
    main()

好的,对此进行跟进。感谢您的 cmets @MarcinMożejko。你是对的。我应该提到更多错误。在 def fit() 中,我写了 model = KerasClassifier,而不是 self.model=Keras Classifier。我想提一下,如果有人在看代码。我现在在同一行收到一个新错误:

AttributeError: 'NoneType' 对象没有属性 'loss'。

我可以追溯到 scikit_learn.py:

loss_name = self.model.loss
        if hasattr(loss_name, '__name__'):
            loss_name = loss_name.__name__
        if loss_name == 'categorical_crossentropy' and len(y.shape) != 2:
            y = to_categorical(y) 

我不确定如何解决这个问题,因为我在 self.model.compile 中设置了损失项。我尝试将其更改为 binary_crossentropy 但没有效果。还有什么想法吗?

【问题讨论】:

【参考方案1】:

问题出在这行代码:

grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)

不幸的是 - 目前,keras 不支持将 pickle 应用于您的模型,这是 sklearn 应用多处理所需的(here 您可以阅读有关此的讨论)。为了使此代码正常工作,您应该设置:

grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=1)

【讨论】:

感谢您的 cmets @MarcinMożejko。你是对的。我应该提到更多错误。在 def fit() 中,我写了 model = KerasClassifier,而不是 self.model=Keras Classifier。我想提一下,如果有人在看代码。我现在在同一行收到一个新错误:AttributeError: 'NoneType' object has no attribute 'loss'。 对于给定的错误,大约有十几种不同的解决方案,这是唯一对我有用的。谢谢!

以上是关于Keras KerasClassifier gridsearch TypeError: can't pickle _thread.lock objects的主要内容,如果未能解决你的问题,请参考以下文章

Keras KerasClassifier gridsearch TypeError: can't pickle _thread.lock objects

无法克隆对象 <keras.wrappers.scikit_learn.KerasClassifier object at 0x7f9d95dd50f0>,因为构造函数要么未设置

尽管一切正常,但 KerasClassifier 无法拟合模型

sklearn RandomizedSearchCV 与流水线 KerasClassifier

如何将 KerasClassifier、Hyperopt 和 Sklearn 交叉验证放在一起

TypeError:“NoneType”类型的对象在尝试适合 KerasCLassifier 时没有 len()