【问题标题】:Problem: Export python tensorflow model and load it in ML.Net问题:导出python tensorflow模型并将其加载到ML.Net中
【发布时间】:2020-11-21 12:37:35
【问题描述】:

我正在尝试使用 ML.Net 和 keras,但我有一些疑问和问题,也许我可以找到答案:

我想要实现的目标:在 Keras 中创建一个简单的 NN,具有一个隐藏层、7 个输入和 10 个输出。 导出该模型,将其导入 ML.Net 并在那里进行预测。 第 1 部分: Python代码:

features_train = ///an array of 3000x7(values between 0 - 1)
labels_train = //an array(vector) of 3000x1 (with the values between 0-9)

model = tf.keras.models.Sequential([
    tf.keras.layers.InputLayer(input_shape=(7,), dtype=float, name='Features'),
    tf.keras.layers.Dense(50, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax',name='Prediction/Softmax'),
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy']
)

model.fit(features_train, labels_train, epochs=100)
model.save(path_to_save_file, save_format='tf')

如果我将它保存在 h5 中并用 netron 打开它,我会得到以下图表(看起来不错)

第一个问题:如果我设置输入层的名称=“Features”,为什么它在模型中没有保存为“Features”,而是保存为“input”?输出层命名正确。

第二个问题:如果我把它保存为“tf”格式,整个图在netron里就乱了,名字变了,你看不懂很多东西(也报道了here) 为什么?

第 2 部分: 我在VS中导入模型(pb文件和变量),并输入以下代码:

class House
{
    public float Bathrooms { get; set; }
    public float SqftLiving { get; set; }
    public float SqftLot { get; set; }
    public float Floors { get; set; }
    public float YearBuild { get; set; }
    public float YearRenovated { get; set; }
    public float Price { get; set; }

}

class Prediction
{
    [VectorType(10)]
    public float[] Scores { get; set; }
}


 class Program
    {
        static void Main(string[] args)
        {
            var mlContext = new MLContext();
            var tensorFlowModel = mlContext.Model.LoadTensorFlowModel("....pathToModel"); 

            var pipeline = mlContext.Transforms.Concatenate("Features",
                    new[] { "Bathrooms", "SqftLiving", "SqftLot", "Floors", "YearBuild", "YearRenovated", "Price" })
                .Append(tensorFlowModel.ScoreTensorFlowModel("Prediction/Softmax", "Features"))
                .Append(mlContext.Transforms.CopyColumns("Scores", "Prediction/Softmax"));

            var dataView = mlContext.Data.LoadFromEnumerable(Enumerable.Empty<House>(), tensorFlowModel.GetModelSchema());
            var transformer = pipeline.Fit(dataView);

            var engine = mlContext.Model.CreatePredictionEngine<House, Prediction>(transformer);

        }

    }

创建管道时出现此错误:Tensorflow.ValueError: 'Could not find operation "Features" inside graph "grap-key-1/".'

我做到这一点的唯一方法是不再使用带有tf格式的save_model,而是将其保存为h5文件,然后通过keras2onnx将其转换为onnx,并通过ApplyOnnxModel在.net中使用onnx文件。

使用 tf,输入模式如下所示:

如您所见,输入是混乱的,输入层的名称是“serving_default_Features”而不是Features,您看不到输出层是如何调用的。

你知道为什么使用python生成的pb文件会抛出这个错误吗?

谢谢^_^

【问题讨论】:

  • 你有完整的代码吗?真的需要这个项目使用onnx模型在ml net中学习

标签: python tensorflow keras ml.net


【解决方案1】:

好的,我找到了 .net 问题的答案。 ML.Net.Tensorflow 想要一个冻结模型。 因此,如果将来有人遇到这些问题:我可以使用 https://hellobird.tistory.com/399 冻结 keras 生成的模型(经过几次适应 Tf2 之后)并使用生成的 pb(没有 pbtxt)文件在 VS 中打开它(你有提供 mlContext.Model.LoadTensorflowModel 的完整路径(包括文件名)(在 ML.Net 的情绪分析示例中只是文件夹),否则会引发异常)。

另外,我必须使用 Netron 检查模型以查看 pb 文件中实际输入/输出层的名称,以便我可以在 c# 中调整管道(例如,输入层被命名为 Features_8)。在对 c# 代码进行这些更改之后,它就可以工作了。

参考:https://github.com/dotnet/machinelearning/issues/5487

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2021-09-08
    相关资源
    最近更新 更多