【问题标题】:How to pickle Keras model?如何腌制 Keras 模型?
【发布时间】:2018-06-26 00:17:59
【问题描述】:

官方文档声明“不建议使用pickle或cPickle来保存Keras模型。”

但是,我对酸洗 Keras 模型的需求源于使用 sklearn 的 RandomizedSearchCV(或任何其他超参数优化器)进行的超参数优化。必须将结果保存到文件中,因为这样脚本可以在分离的会话等中远程执行。

基本上,我想:

trial_search = RandomizedSearchCV( estimator=keras_model, ... )
pickle.dump( trial_search, open( "trial_search.pickle", "wb" ) )

【问题讨论】:

  • 本题同样适用于Tensorflow等其他深度学习框架
  • Keras 推荐使用model.save()。 Scikitrecommends joblib。使用 RandomizedSearchCV 调整参数后,您可以使用 trial_search.best_estimator_ 来获得最适合的模型,然后使用 keras 推荐的方法。为什么还要保存 RandomizedSearhCV 对象?
  • 因为您想保存搜索的历史记录以及所有详细信息,例如,我想知道第二好的结果是什么样的以及它使用了哪些参数,追溯.
  • 然后,您应该寻找保存 cv_results_ 属性而不是完整的 RandomizedSearchCV,这将是一个包含您需要的所有信息的字典。
  • 根据定义,如果您不保存整个对象,您将丢失信息。例如,在以后的日子里,我突然想比较第 3 佳模型的权重和第 5 佳模型的权重。现在我必须重新运行这些模型,而不是 pickle.load()。我不能吗?另外,我不想附加到sklearn,因为我想在以后使用其他超参数优化器。

标签: python machine-learning keras pickle


【解决方案1】:

截至目前,Keras 模型是可腌制的。但我们仍然建议使用model.save() 将模型保存到磁盘。

【讨论】:

  • 我在 keras 常见问题解答中看到了建议,但我想知道为什么 model.save() 更喜欢酸洗,你能在你的回答中澄清这一点吗?
  • 使用 model.save() 保存的模型将与 Keras 的未来版本兼容,也可以导出到其他平台和实现(deeplearning4j、Apple CoreML 等)。
  • model.save() 在 python3 中存在问题。每次我加载模型时,它都会为相同的输入预测不同的东西。
  • @user2814799 这还是真的吗!?
【解决方案2】:

这就像一个魅力http://zachmoshe.com/2017/04/03/pickling-keras-models.html

import types
import tempfile
import keras.models

def make_keras_picklable():
    def __getstate__(self):
        model_str = ""
        with tempfile.NamedTemporaryFile(suffix='.hdf5', delete=True) as fd:
            keras.models.save_model(self, fd.name, overwrite=True)
            model_str = fd.read()
        d = { 'model_str': model_str }
        return d

    def __setstate__(self, state):
        with tempfile.NamedTemporaryFile(suffix='.hdf5', delete=True) as fd:
            fd.write(state['model_str'])
            fd.flush()
            model = keras.models.load_model(fd.name)
        self.__dict__ = model.__dict__


    cls = keras.models.Model
    cls.__getstate__ = __getstate__
    cls.__setstate__ = __setstate__

make_keras_picklable()

PS。我遇到了一些问题,因为我的model.to_json() 由于循环引用而引发了TypeError('Not JSON Serializable:', obj),并且这个错误已经被上面的代码以某种方式吞没了,因此导致 pickle 函数永远运行。

【讨论】:

  • 我不清楚你如何使用 make_keras_picklable() 来腌制 my_model。你能举个例子吗?
【解决方案3】:

使用 get_weights 和 set_weights 分别保存和加载模型。

看看这个链接:Unable to save DataFrame to HDF5 ("object header message is too large")

#for heavy model architectures, .h5 file is unsupported.
weigh= model.get_weights();    pklfile= "D:/modelweights.pkl"
try:
    fpkl= open(pklfile, 'wb')    #Python 3     
    pickle.dump(weigh, fpkl, protocol= pickle.HIGHEST_PROTOCOL)
    fpkl.close()
except:
    fpkl= open(pklfile, 'w')    #Python 2      
    pickle.dump(weigh, fpkl, protocol= pickle.HIGHEST_PROTOCOL)
    fpkl.close()

【讨论】:

    【解决方案4】:

    您可以使用可以通过 pip 安装的 deploy-ml 模块来腌制 Keras 神经网络

    pip install deploy-ml
    

    使用 deploy-ml 包装器对 kera 神经网络的完整训练和部署如下所示:

    import pandas as pd
    from deployml.keras import NeuralNetworkBase
    
    
    # load data 
    train = pd.read_csv('example_data.csv')
    
    # define the moel 
    NN = NeuralNetworkBase(hidden_layers = (7, 3),
                       first_layer=len(train.keys())-1, 
                       n_classes=len(train.keys())-1)
    
    # define data for the model 
    NN.data = train
    
    # define the column in the data you're trying to predict
    NN.outcome_pointer = 'paid'
    
    # train the model, scale means that it's using a standard 
    # scaler to scale the data
    NN.train(scale=True, batch_size=100)
    
    NN.show_learning_curve()
    
    # display the recall and precision 
    NN.evaluate_outcome()
    
    # Pickle your model
    NN.deploy_model(description='Keras NN',
                author="maxwell flitton", organisation='example',
                file_name='neural.sav')
    

    Pickled 文件包含模型、测试指标、变量名称列表及其输入顺序、使用的 Keras 和 python 版本,如果使用缩放器,它也将是存储在文件中。文档是here。通过以下方式加载和使用文件:

    import pickle
    
    # use pickle to load the model 
    loaded_model = pickle.load(open("neural.sav", 'rb'))
    
    # use the scaler to scale your data you want to input 
    input_data = loaded_model['scaler'].transform([[1, 28, 0, 1, 30]])
    
    # get the prediction 
    loaded_model['model'].predict(input_data)[0][0]
    

    我很欣赏培训可能会有些限制。 Deploy-ml 支持为 Sk-learn 导入您自己的模型,但它仍在努力为 Keras 提供这种支持。但是,我发现您可以创建一个 deploy-ml NeuralNetworkBase 对象,在 Deploy-ml 之外定义您自己的 Keras 神经网络,并将其分配给 deploy-ml 模型属性,这样就可以正常工作:

     NN = NeuralNetworkBase(hidden_layers = (7, 3),
                   first_layer=len(train.keys())-1, 
                   n_classes=len(train.keys())-1)
    
    NN.model = neural_network_you_defined_yourself
    

    【讨论】:

      猜你喜欢
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      • 2018-04-14
      • 1970-01-01
      • 2018-11-22
      • 2020-10-11
      • 1970-01-01
      相关资源
      最近更新 更多