AI机器学习(五)Keras h5转onnx C# ML 推理

依赖:安装Tesnsorflow 2.0、安装Python3.7以上、安装VSCode、Windows操作系统

一、模型转换

1.1 装载模型

创建VSCode项目目录,并打开文件夹

--model_4
  --model.h5
  --model.json
--main.py

根据文件加载json模型和weight数据

import os
from tensorflow import keras
import tensorflow as tf
import numpy as np

class Model:
    def __init__(self, load_quantize=False):
        keras.backend.set_learning_phase(0)
        self.__load_model()
    def __load_model(self, dir="model_4"): 
        with open(os.path.join(dir, "model.json"), "r") as f:        
            loaded_model_json = f.read()
        #装载模型数据
        self.model = keras.models.model_from_json(loaded_model_json)
        #装载模型训练参数
        self.model.load_weights(os.path.join(dir, "model.h5"))
    def __compile_model(self):
        self.model.compile(optimizer=keras.optimizers.Adam(),
              loss=keras.losses.categorical_crossentropy,
              metrics=["accuracy"])      

转储模型

import tensorflow as tf

model = Model()
tf.saved_model.save(model.model, "onnx_model")

1.2 执行转换

pip install tf2onnx

python -m tf2onnx.convert --saved-model football_player_classific_model --output "model.onnx" 

1.3 查看model.onnx

下载Netron并默认安装

https://github.com/lutzroeder/netron/releases/tag/v6.2.3

打开模型文件,查看首个input

如:input_11

二、C#应用onnx

安装机器学习运行时Nuget

Microsoft.ML.OnnxRuntime

安装OpenCV包及依赖

OpenCvSharp4
OpenCvSharp4.Extensions
OpenCvSharp4.runtime.win
Numpy.Bare

基础扩展函数

/// <summary>
/// 张量转换
/// </summary>
/// <param name="darray"></param>
/// <returns></returns>
public static DenseTensor<float> ToDenseTensor(this NDarray darray,int size = 80)
{
    
    
    var memory = darray.astype(np.float32).GetData<float>();
    var inputTensor = new DenseTensor<float>(memory, darray.shape.Dimensions);
    return inputTensor;
}
/// <summary>
/// MatToNDarray(RGB转换)
/// </summary>
/// <param name="frameMat"></param>
/// <returns></returns>
public static NDarray ToNDarray(this Mat frameMat)
{
    
    
    var newimage = frameMat.Reshape(1);
    newimage.GetArray(out byte[] imageArray);
    var array = Numpy.np.array(imageArray, dtype: np.uint8).reshape(frameMat.Rows, frameMat.Cols, frameMat.Channels());
    array = np.expand_dims(array, 0);
    return array;
}

基础图像加载函数

public class LoadImages
{
    
    
    public static Mat Load(string file)
    {
    
    
          var basepath = AppDomain.CurrentDomain.BaseDirectory;
          var fileFullPath = Path.Combine(basepath, "Assets", file);
          var filemat = Cv2.ImRead(fileFullPath);
          return filemat;
    }
    public static IEnumerable<Mat> LoadVideo(string file)
    {
    
    
        Mat imageOriginal = new Mat();
        using (var videocapture = new VideoCapture(file))
        {
    
    
          while (videocapture.Read(imageOriginal))
             yield return imageOriginal;
        }
    }
}

模型应用函数(类

 public class ClassificWithOnnx
 {
    
    
    /// <summary>
    /// 预测(推理)
    /// </summary>
    public static NDarray Predict(NDarray? inputs)
    {
    
    
        //NDarry转为张量,输入是Nx80像素x80像素x3RGB
        var inputTensor = inputs?.ToDenseTensor();
        //需要明确指出模型的输入参数名字,如果不知道,请使用工具Netron
        var input = new List<NamedOnnxValue> {
    
     NamedOnnxValue.CreateFromTensor<float>("input_11", inputTensor) };
        var session = new InferenceSession(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Assets/model.onnx"));
        var outputs = session?.Run(input).ToList().Last().AsEnumerable<float>().ToArray();
        var outputarray = np.array<float>(outputs!);
        //输出是Nx3
        var arr = outputarray.reshape(inputs!.shape.Dimensions[0], 3);
        //取列最大值,也就是分类得分最高的结果,输出为NX1
        arr = np.argmax(arr, axis: 1);
        return arr;
    }
 }

单元测试函数

[Fact]
public void TestMLFromOnnx()
{
    
    
    using (var mat = LoadImages.Load("classific.png"))
    {
    
    
        var array = mat.ToNDarray();
        //我的模型是需要多个数据合并为一个input_11的
        array = np.concatenate((array, array));
        var arr= ClassificWithOnnx.Predict(array);
        //模型输出是0,1,2的分类结果
        Assert.True(arr?.item<int>(0) == 0);
    }
}

猜你喜欢

转载自blog.csdn.net/black0707/article/details/128197819