我正在尝试腌制一个sklearn机器学习模型,并将其加载到另一个项目中。该模型包装在具有编码,缩放等功能的管道中。当我想在管道中使用自写转换器执行更高级的任务时,问题就开始了。
假设我有2个专案:
如果在“ train_project”中使用joblib.dump()保存管道,然后在“ use_project”中通过joblib.load()加载管道,则找不到“ src.feature_extraction.transformers”之类的东西并抛出异常:
ModuleNotFoundError:没有名为“ src.feature_extraction”的模块
我还应该补充一点,我的初衷是简化模型的使用,以便程序员可以像其他模型一样加载模型,传递非常简单的,人类可读的特征以及对实际模型进行所有“神奇”的特征预处理(例如内部发生梯度提升)。
我想到了在两个项目的根目录中创建/ dependencies / xxx_model /目录,并在其中存储所有需要的类和函数(将代码从“ train_project”复制到“ use_project”),因此项目的结构是相等的,可以加载转换器。我发现此解决方案非常笨拙,因为它将强制使用该模型的任何项目的结构。
我想到了只是重新创建“ use_project”中的管道和所有变压器,并以某种方式从“ train_project”中加载变压器的拟合值。
最好的解决方案是,如果转储的文件包含所有需要的信息并且不需要依赖,我真的为sklearn.Pipelines感到震惊-如果我以后无法加载适合的对象,适合管道的意义何在?是的,如果我仅使用sklearn类,而不创建自定义类,但非自定义类没有所有必需的功能,则它将起作用。
示例代码:
train_project
src.feature_extraction.transformers.py
from sklearn.pipeline import TransformerMixin
class FilterOutBigValuesTransformer(TransformerMixin):
def __init__(self):
pass
def fit(self, X, y=None):
self.biggest_value = X.c1.max()
return self
def transform(self, X):
return X.loc[X.c1 <= self.biggest_value]
Run Code Online (Sandbox Code Playgroud)
train_project
main.py
from sklearn.externals import joblib
from sklearn.preprocessing import MinMaxScaler
from src.feature_extraction.transformers import FilterOutBigValuesTransformer
pipeline = Pipeline([
('filter', FilterOutBigValuesTransformer()),
('encode', MinMaxScaler()),
])
X=load_some_pandas_dataframe()
pipeline.fit(X)
joblib.dump(pipeline, 'path.x')
Run Code Online (Sandbox Code Playgroud)
test_project
main.py
from sklearn.externals …Run Code Online (Sandbox Code Playgroud) 我开始着手研究使用Flask将预测模型部署到Web应用程序,但不幸地陷入了起步阶段。
我做了什么:
我在model.py程序中腌制了模型:
import numpy as np
from sklearn.externals import joblib
class NeuralNetwork():
"""
Two (hidden) layer neural network model.
First and second layer contain the same number of hidden units
"""
def __init__(self, input_dim, units, std=0.0001):
self.params = {}
self.input_dim = input_dim
self.params['W1'] = np.random.rand(self.input_dim, units)
self.params['W1'] *= std
self.params['b1'] = np.zeros((units))
self.params['W2'] = np.random.rand(units, units)
self.params['W2'] *= std * 10 # Compensate for vanishing gradients
self.params['b2'] = np.zeros((units))
self.params['W3'] = np.random.rand(units, 1)
self.params['b3'] = np.zeros((1,))
model …Run Code Online (Sandbox Code Playgroud)