pickle/joblib AttributeError: module '__main__' has no attribute 'thing' in pytest
pickle/joblib AttributeError: module '__main__' has no attribute 'thing' in pytest
我已经构建了一个自定义的sklearn管道,如下:
pipeline = make_pipeline(
SelectColumnsTransfomer(features_to_use),
ToDummiesTransformer('feature_0', prefix='feat_0', drop_first=True, dtype=bool), # Dummify customer_type
ToDummiesTransformer('feature_1', prefix='feat_1'), # Dummify the feature
ToDummiesTransformer('feature_2', prefix='feat_2'), # Dummify
ToDummiesTransformer('feature_3', prefix='feat_3'), # Dummify
)
pipeline.fit(df)
类 SelectColumnsTransfomer
和 ToDummiesTransformer
是实现 BaseEstimator
和 TransformerMixin
的自定义 sklearn 步骤。
为了序列化这个对象,我使用
from sklearn.externals import joblib
joblib.dump(pipeline, 'data_pipeline.joblib')
但是当我用
反序列化时
pipeline = joblib.load('data_pipeline.joblib')
我得到 AttributeError: module '__main__' has no attribute 'SelectColumnsTransfomer'
。
我已阅读其他类似问题并按照此博文 here 中的说明进行操作,但无法解决问题。
我正在复制粘贴 类,并将它们导入代码中。如果我创建此练习的简化版本,整个过程都有效,但出现问题是因为我 运行 正在使用 pytest 进行一些测试,而当我 运行 pytest 时,它似乎没有看到我的自定义类,其实还有这部分错误
self = <sklearn.externals.joblib.numpy_pickle.NumpyUnpickler object at 0x7f821508a588>, module = '__main__', name = 'SelectColumnsTransfomer'
这暗示我 NumpyUnpickler
看不到 SelectColumnsTransfomer
即使在测试中它是导入的。
我的测试代码
import pytest
from app.pipeline import * # the pipeline objects
# SelectColumnsTransfomer and ToDummiesTransformer
# are here!
@pytest.fixture(scope="module")
def clf():
pipeline = joblib.load("persistence/data_pipeline.joblib")
return clf
def test_fake(clf):
assert True
好的,我发现问题了。我发现这个问题与我原先认为的Python: pickling and dealing with "AttributeError: 'module' object has no attribute 'Thing'"博文中解释的问题无关。
您可以通过对文件进行酸洗和取消酸洗来轻松解决问题。我使用一个单独的脚本(一个 Jupyther 笔记本)来 pickle 和一个普通的 [python 脚本来 unpicle。当我在同一个 class 中完成所有操作时,它起作用了。
当我尝试像这样保存 Pytorch class 时收到相同的错误消息:
import torch.nn as nn
class custom(nn.Module):
def __init__(self):
super(custom, self).__init__()
print("Class loaded")
model = custom()
然后像这样使用 Joblib 转储此模型:
from joblib import dump
dump(model, 'some_filepath.jobjib')
问题是我在 Kaggle 内核中 运行ning 上面的代码。然后下载转储文件并尝试在本地使用此脚本加载它:
from joblib import load
model = load(model, 'some_filepath.jobjib')
我解决这个问题的方法是 运行 所有这些代码片段都在我的本地计算机上,而不是创建 class 并将其转储到 Kaggle 上,而是加载它在我的本地机器上。想在这里添加这个,因为@DarioB 对 的评论让我感到困惑,因为他们提到了 'function',这不适用于我更简单的情况。
我已经构建了一个自定义的sklearn管道,如下:
pipeline = make_pipeline(
SelectColumnsTransfomer(features_to_use),
ToDummiesTransformer('feature_0', prefix='feat_0', drop_first=True, dtype=bool), # Dummify customer_type
ToDummiesTransformer('feature_1', prefix='feat_1'), # Dummify the feature
ToDummiesTransformer('feature_2', prefix='feat_2'), # Dummify
ToDummiesTransformer('feature_3', prefix='feat_3'), # Dummify
)
pipeline.fit(df)
类 SelectColumnsTransfomer
和 ToDummiesTransformer
是实现 BaseEstimator
和 TransformerMixin
的自定义 sklearn 步骤。
为了序列化这个对象,我使用
from sklearn.externals import joblib
joblib.dump(pipeline, 'data_pipeline.joblib')
但是当我用
反序列化时pipeline = joblib.load('data_pipeline.joblib')
我得到 AttributeError: module '__main__' has no attribute 'SelectColumnsTransfomer'
。
我已阅读其他类似问题并按照此博文 here 中的说明进行操作,但无法解决问题。
我正在复制粘贴 类,并将它们导入代码中。如果我创建此练习的简化版本,整个过程都有效,但出现问题是因为我 运行 正在使用 pytest 进行一些测试,而当我 运行 pytest 时,它似乎没有看到我的自定义类,其实还有这部分错误
self = <sklearn.externals.joblib.numpy_pickle.NumpyUnpickler object at 0x7f821508a588>, module = '__main__', name = 'SelectColumnsTransfomer'
这暗示我 NumpyUnpickler
看不到 SelectColumnsTransfomer
即使在测试中它是导入的。
我的测试代码
import pytest
from app.pipeline import * # the pipeline objects
# SelectColumnsTransfomer and ToDummiesTransformer
# are here!
@pytest.fixture(scope="module")
def clf():
pipeline = joblib.load("persistence/data_pipeline.joblib")
return clf
def test_fake(clf):
assert True
好的,我发现问题了。我发现这个问题与我原先认为的Python: pickling and dealing with "AttributeError: 'module' object has no attribute 'Thing'"博文中解释的问题无关。 您可以通过对文件进行酸洗和取消酸洗来轻松解决问题。我使用一个单独的脚本(一个 Jupyther 笔记本)来 pickle 和一个普通的 [python 脚本来 unpicle。当我在同一个 class 中完成所有操作时,它起作用了。
当我尝试像这样保存 Pytorch class 时收到相同的错误消息:
import torch.nn as nn
class custom(nn.Module):
def __init__(self):
super(custom, self).__init__()
print("Class loaded")
model = custom()
然后像这样使用 Joblib 转储此模型:
from joblib import dump
dump(model, 'some_filepath.jobjib')
问题是我在 Kaggle 内核中 运行ning 上面的代码。然后下载转储文件并尝试在本地使用此脚本加载它:
from joblib import load
model = load(model, 'some_filepath.jobjib')
我解决这个问题的方法是 运行 所有这些代码片段都在我的本地计算机上,而不是创建 class 并将其转储到 Kaggle 上,而是加载它在我的本地机器上。想在这里添加这个,因为@DarioB 对