更正 pb 文件以将 Tensorflow 模型移动到 ML.NET

Correct pb file to move Tensorflow model into ML.NET

我有一个我构建的 TensorFlow 模型(一维 CNN),我现在想将其实施到 .NET 中。
为此,我需要了解输入和输出节点。
当我在 Netron 上上传模型时,根据我的保存方法,我得到了不同的图表,唯一看起来正确的图表来自 h5 上传。这是 model.summary():

如果我将模型保存为 h5 model.save("Mn_pb_model.h5") 并将其加载到 Netron 中进行绘图,一切看起来都是正确的:

但是ML.NET不接受h5格式所以需要保存为pb格式

在查看 ML.NET 中采用 TensorFlow 的样本时,这个 sample shows a TensorFlow model that is saved in a similar format to the SavedModel format - recommended by TensorFlow (and also recommended by ML.NET here“下载解冻的 [SavedModel 格式] ...”)。但是,当将 pb 文件保存并加载到 Netron 中时,我得到了这个:

再放大一点(在最右边),

如您所见,它看起来完全不像应有的样子。
此外,输入节点和输出节点不正确,因此它不适用于 ML.NET(我认为有问题)。
我正在使用 TensorFlow 中的 recommended way 来确定输入/输出节点:

当我尝试获取一个 图表并将其加载到 Netron 中时,起初它看起来是正确的,但我不认为它是:

有四个原因我认为这是不正确的。

此外,在查看 Inception 的 model.summary() 及其图表时,它与图表的相似之处与我的 model.summary() 与 h5 图表的相似之处。

似乎应该有一种更简单的方法(也是一种正确的方法)来保存 TensorFlow 模型,以便它可以用于 ML.NET。

请证明您建议的解决方案有效: 在您提供的答案中,请检查它是否有效(加载 pb 模型 [这也应该有一个Variables 文件夹以便 ML.NET] 进入 Netron 并显示它与 h5 模型相同,例如截图)。为了让我们都在尝试同样的事情,这里有一个 link 到 MNIST ML 速成课程示例。 运行 程序用了不到 30 秒,并生成了一个名为 my_model 的模型。从这里您可以根据您的方法保存它并上传它以查看 Netron 上的图形。这是 h5 模型上传:

这个答案由三部分组成:

  • 正在学习其他程序
  • 不通过其他程序
  • 操作级图概念图之间的区别(以及为什么 Netron 显示不同的图)

1.通过其他程序:

ML.net 需要 ONNX 模型,而不是 pb 文件。

有多种方法可以将您的模型从 TensorFlow 转换为您可以在 ML.net 中加载的 ONNX 模型:

这个 SO post 也可以帮助你:

在这里您可以找到有关 h5 和 pb 文件格式及其包含的内容等的更多信息:https://www.tensorflow.org/guide/keras/save_and_serialize#weights_only_saving_in_savedmodel_format

2。但是你问的是“TensorFlow -> ML.NET 没有经过其他程序”:

2.A 问题概述:

首先,根据您所说的,您使用您提供的代码制作的 pl 文件格式似乎与您在评论中提到的示例中使用的格式不同(https://docs.microsoft.com/en-us/dotnet/machine-learning/tutorials/text-classification-tf)

可以尝试使用将通过 tf.saved_model.save 生成的 pb 文件吗?有用吗?

关于这个微软博客的想法 post:

this page我们可以读到:

In ML.NET you can load a frozen TensorFlow model .pb file (also called “frozen graph def” which is essentially a serialized graph_def protocol buffer written to disk)

和:

That TensorFlow .pb model file that you see in the diagram (and the labels.txt codes/Ids) is what you create/train in Azure Cognitive Services Custom Vision then exporte as a frozen TensorFlow model file to be used by ML.NET C# code.

因此,此 pb 文件是一种从 Azure 认知服务自定义视觉生成的文件。 也许你也可以尝试这种方式?

2.B 现在,我们将尝试提供解决方案:

事实上,在 TensorFlow 1.x 中,您可以使用 freeze_graph.

轻松保存冻结图

但 TensorFlow 2.x 不支持 freeze_graphconverter_variables_to_constants

您也可以在这里阅读一些有用的信息:

一些用户想知道在 TF 中如何做 2.x:如何在 tensorflow 2.0 中冻结图形 (https://github.com/tensorflow/tensorflow/issues/27614)

但是有一些解决方案可以创建 pb 文件,您可以根据需要在 ML.net 中加载:

https://leimao.github.io/blog/Save-Load-Inference-From-TF2-Frozen-Graph/

(虽然已在您的问题中链接)

操作级图概念图之间的区别(以及为什么 Netron 显示不同的图):

正如@mlneural03 在对您提问的评论中所说,Netron 会根据您提供的文件格式显示不同的图表:

  • 如果加载h5文件,Netron会显示概念图
  • 如果你加载一个 pb 文件,Netron 将显示操作级图

操作级图和概念图有什么区别?

  • 在 TensorFlow 中,op 级图的节点表示操作(“ops”),如 tf.add 、tf.matmul 、tf.linalg.inv 等
  • 概念图将显示模型的结构。

那是完全不同的事情。

“ops”是“operations”的缩写。 操作是执行计算的节点。

所以,这就是为什么当您在 Netron 中加载 pb 文件时会得到一个包含很多节点的非常大的图:您会看到该图的所有计算节点。 但是当你在 Netron 中加载 h5 文件时,你“只是”看到你的模型的结构,你的模型的设计。

在 TensorFlow 中,您可以使用 TensorBoard 查看图表:

  • 默认情况下,TensorBoard 显示操作级图。
  • 要查看概念图,在 TensorBoard 中,select“keras”标签。

有一个 Jupyter Notebook 在这里非常清楚地解释了 op-level graph 和 coneptual graph 之间的区别:https://colab.research.google.com/github/tensorflow/tensorboard/blob/master/docs/graphs.ipynb

您也可以在 TensorFlow Github 上阅读此“问题”,与您的问题相关:https://github.com/tensorflow/tensorflow/issues/39699

简而言之:

其实没什么问题,就是有点误会(没关系,我们不可能什么都知道)。

您希望在 Netron 中加载 h5 文件和 pb 文件时看到相同的图表,但是 必须 不成功,因为文件不包含相同的图形。这些图表是显示同一模型的两种方式。

使用我们描述的方法创建的 pb 文件将是 ML.NET 加载的正确 pb 文件,如我们讨论的 Microsoft 教程中所述。因此,如果您按照这些教程中的描述加载正确的 pb 文件,您将加载 real/true 模型。