深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型

前言

作者通过简单的例子详细介绍了如何将训练过程中的深度学习模型保存,然后如何加载。有了这个小技巧,再也不用担心在训练模型中出错了。

一:如何保存和恢复TensorFlow训练的模型

如果深层神经网络模型的复杂度非常高的话,那么训练它可能需要相当长的一段时间,当然这也取决于你拥有的数据量,运行模型的硬件等等。在大多数情况下,你需要通过保存文件来保障你试验的稳定性,防止如果中断(或一个错误),你能够继续从没有错误的地方开始。

更重要的是,对于任何深度学习的框架,像TensorFlow,在成功的训练之后,你需要重新使用模型的学习参数来完成对新数据的预测。

在这篇文章中,我们来看一下如何保存和恢复TensorFlow模型,我们在此介绍一些最有用的方法,并提供一些例子。

1.首先我们将快速介绍TensorFlow模型

TensorFlow的主要功能是通过张量来传递其基本数据结构类似于NumPy中的多维数组,而图表则表示数据计算。它是一个符号库,这意味着定义图形和张量将仅创建一个模型,而获取张量的具体值和操作将在会话(session)中执行,会话(session)一种在图中执行建模操作的机制。会话关闭时,张量的任何具体值都会丢失,这也是运行会话后将模型保存到文件的另一个原因。

通过示例可以帮助我们更容易理解,所以让我们为二维数据的线性回归创建一个简单的TensorFlow模型。

首先,我们将导入我们的库:

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

下一步是创建模型。我们将生成一个模型,它将以以下的形式估算二次函数的水平和垂直位移:

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

其中h是水平和v是垂直的变化。

以下是如何生成模型的过程(有关详细信息,请参阅代码中的注释):

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

在创建模型的过程中,我们需要有一个在会话中运行的模型,并且传递一些真实的数据。我们生成一些二次数据(Quadratic data),并给他们添加噪声。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》 《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

2.The Saver class

Saver类是TensorFlow库提供的类,它是保存图形结构和变量的首选方法。

2.1保存模型

在以下几行代码中,我们定义一个Saver对象,并在train_graph()函数中,经过100次迭代的方法最小化成本函数。然后,在每次迭代中以及优化完成后,将模型保存到磁盘。每个保存在磁盘上创建二进制文件被称为“检查点”。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

现在让我们用上述功能训练模型,并打印出训练的参数。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

Okay,参数是非常准确的。如果我们检查我们的文件系统,最后4次迭代中保存有文件以及最终的模型。

保存模型时,你会注意到需要4种类型的文件才能保存:

“.meta”文件:包含图形结构。

“.data”文件:包含变量的值。

“.index”文件:标识检查点。

“checkpoint”文件:具有最近检查点列表的协议缓冲区。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

图1:检查点文件保存到磁盘

调用tf.train.Saver()方法,如上所示,将所有变量保存到一个文件。通过将它们作为参数,表情通过列表或dict传递来保存变量的子集,例如:tf.train.Saver({'hor_estimate': h_est})

Saver构造函数的一些其他有用的参数,也可以控制整个过程,它们是:

1.max_to_keep:最多保留的检查点数。

2.keep_checkpoint_every_n_hours:保存检查点的时间间隔。

如果你想要了解更多信息,请查看官方文档Saver类,它提供了其它有用的信息,你可以探索查看。

3.Restoring Models

恢复TensorFlow模型时要做的第一件事就是将图形结构从“.meta”文件加载到当前图形中。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

也可以使用以下命令探索当前图形tf.get_default_graph()。接着第二步是加载变量的值。提醒:值仅存在于会话(session)中。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

如前面所提到的,这种方法只保存图形结构和变量,这意味着通过占位符“X”和“Y”输入的训练数据不会被保存。

无论如何,在这个例子中,我们将使用我们定义的训练数据tf,并且可视化模型拟合。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》 《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

Saver这个类允许使用一个简单的方法来保存和恢复你的TensorFlow模型(图形和变量)到/从文件,并保留你工作中的多个检查点,这可能是有用的,它可以帮助你的模型在训练过程中进行微调。

4.SavedModel格式(Format)

在TensorFlow中保存和恢复模型的一种新方法是使用SavedModel,Builder和loader功能。这个方法实际上是Saver提供的更高级别的序列化,它更适合于商业目的。

虽然这种SavedModel方法似乎不被开发人员完全接受,但它的创作者指出:它显然是未来。与Saver主要关注变量的类相比,SavedModel尝试将一些有用的功能包含在一个包中,例如Signatures:允许保存具有一组输入和输出的图形,Assets:包含初始化中使用的外部文件。

4.1使用SavedModel Builder保存模型

接下来我们尝试使用SavedModelBuilder类完成模型的保存。在我们的示例中,我们不使用任何符号,但也足以说明该过程。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

运行此代码时,你会注意到我们的模型已保存到位于“./SavedModel/saved_model.pb”的文件中。

4.2使用SavedModel Loader程序恢复模型

模型恢复使用tf.saved_model.loader,并且可以恢复会话范围中保存的变量,符号。

在下面的例子中,我们将加载模型,并打印出我们的两个系数(h_estv_est)的数值。数值如预期的那样,我们的模型已经被成功地恢复了。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

5.结论

如果你知道你的深度学习网络的训练可能会花费很长时间,保存和恢复TensorFlow模型是非常有用的功能。该主题太广泛,无法在一篇博客文章中详细介绍。不管怎样,在这篇文章中我们介绍了两个工具:SaverSavedModel builder/loader,并创建一个文件结构,使用简单的线性回归来说明实例。希望这些能够帮助到你训练出更好的神经网络模型。

二:如何保存和恢复scikit-learn训练的模型

在许多情况下,在使用scikit学习库的同时,你需要将预测模型保存到文件中,然后在使用它们的时候还原它们,以便重复使用以前的工作。比如在新数据上测试模型,比较多个模型的优劣。这种保存过程也称为对象序列化——表示具有字节流的对象,以便将其存储在磁盘上,它可以通过网络发送或保存到数据库,而其恢复的过程被称为反序列化。在本文中,我们将在Python和scikit学习中看到三种可能的方法,而且每种都有其优点和缺点。

1.保存和恢复模型的工具

我们第一个介绍的工具是Pickle,用于对象(de)序列化的标准Python工具。之后,我们会介绍Joblib库,它提供了容易(de)序列化方法,其中包含了大数据数组的对象,最后我们会介绍一种手动方法来保存和恢复JSON对象(JavaScript Object Notation)。这些方法都不能代表最佳解决方案,但是可以根据项目的需要选择合适的方案。

2.模型初始化

首先,我们要创建一个scikit学习模型。在我们的例子中,我们将使用Logistic回归模型和Iris数据集。我们导入所需的库,并且加载数据,并将其拆分为训练集和测试集。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

现在让我们用一些非默认参数来创建模型,并用训练数据来“喂养”它。我们假设你先前已经找到了模型的最优参数,即产生最高估计精度的参数。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

这是我们产生的模型:

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

使用该fit方法,模型已经学习了存储在其中的系数model.coef_。目标是将模型的参数和系数保存到文件中,因此你不需要再次对新数据重复模型训练和参数优化的步骤。

3.Pickle模块

在以下几行代码中,我们将上一步中创建的模型保存到文件中,然后作为一个新对象加载pickled_model。然后使用加载的模型计算准确度分数,并对新的未见(测试)数据进行预测结果。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

运行此代码应该会产生你的预测分数,并通过Pickle保存模型:

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

使用Pickle来保存和恢复学习模型的好处在于它很快,并且你可以用两行代码完成。如果你已经对训练数据上的模型参数进行了优化,那么这是非常有用的,因此你不需要重复此步骤。不管如何,它都不保存测试结果和任何数据。但仍然可以保存多个对象的元组或列表(并记住哪个对象在哪里),如下所示:

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

3.Joblib模块

Joblib库它的目的是替代Pickle,用于包含大数据的对象。我们将重复与Pickle一样的保存和恢复过程

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

从示例中可以看出,与Pickle相比,Joblib库提供了一个简单的工作流程。虽然Pickle要求将文件对象作为参数传递,但是Joblib可与文件对象和字符串文件名一起使用。如果你的模型包含大量数据,则每个数组将存储在单独的文件中,但整体的保存和恢复过程将保持不变。Joblib还允许使用不同的压缩方法,如“zlib”,“gzip”,“bz2”和不同的压缩级别。

4.手动保存并还原到JSON

根据你的项目,很多时候你会发现Pickle和Joblib都不是合适的解决方案。其中一些原因将在兼容性问题部分中稍后讨论。无论何时要想完全控制保存和恢复过程,最好的方法是手动构建自己的功能。

以下显示了使用JSON手动保存和恢复对象的示例。这种方法允许我们选择需要保存的数据,例如模型参数,系数,训练数据以及我们需要的任何其他数据。

由于我们想将所有这些数据保存在一个对象中,所以一个可能的方法是创建一个继承我们的示例中的模型类的新类LogisticRegression。这个新类被MyLogReg调用,然后分别实现save_jsonload_json的方法以保存和恢复JSON文件。

为简单起见,我们将只保存三个模型参数和训练数据。我们可以用这种方法存储一些额外的数据,例如训练集上的交叉验证分数,测试数据,测试数据的准确度等等。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

现在我们来试一试MyLogReg。首先我们创建一个对象mylogreg,将训练数据传递给它,并将其保存到文件中。然后我们创建一个新对象json_mylogreg,并调用该load_json方法从文件加载数据。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

打印出新的对象,我们可以根据需要来查看我们的参数和训练数据。

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》
《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

由于使用JSON的数据序列化实际上是将对象保存为字符串格式,而不是字节流,所以’mylogreg.json’文件可以使用文本编辑器打开和修改。虽然这种方法对开发人员来说很方便,但是由于入侵者可以查看和修改JSON文件的内容,因此安全性较低。此外,这种方法更适合于具有少量实例变量的对象,例如scikit-learn模型,因为任何添加新变量都需要在保存和恢复方法中进行更改。\

5.兼容性问题

尽管到目前为止,每个工具的优点和缺点已被介绍,但Pickle和Joblib工具的最大缺点可能是其与不同型号的Python版本的兼容性。

5.1:Python版本的兼容性——两种工具的文档都指出,不建议(de)在不同的Python版本之间对对象进行序列化,尽管它可能在低级的版本更改中起作用。

5.2:模型兼容性——最常见的错误之一是使用Pickle或Joblib保存模型,然后在尝试从文件还原之前更改模型。模型的内部结构需要在保存和重新加载之间保持不变。

Pickle和Joblib的最后一个问题与安全性有关。这两种工具都可能包含恶意代码,因此不建议从不受信任或未经身份验证的源代码。

6.结论

在这篇文章中,我们描述了三种保存和恢复scikit学习模型的工具。Pickle和Joblib库可以快速方便地使用,但是在不同的Python版本和学习模型的变化中存在兼容性问题。另一方面,手动方法更难实现,需要在模型结构发生任何变化中进行修改,但在另一方面,它可以轻松地适应各种需求,并且没有任何兼容性问题。

作者信息

《深度学习小技巧:如何保存和恢复TensorFlow、scikit-learn训练的模型》

作者:Mihajlo Pavloski,数据科学与机器学习的爱好者,博士生。

本文由阿里云云栖社区组织翻译。

文章原标题《TensorFlow : Save and Restore Models》

作者:Mihajlo Pavloski 译者:虎说八道,审阅:

文章为简译,更为详细的内容,请查看原文

更多技术干货敬请关注云栖社区知乎机构号:阿里云云栖社区 – 知乎

    原文作者:阿里云云栖社区
    原文地址: https://zhuanlan.zhihu.com/p/30597931
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞