AI Machine Learning (5) Keras h5 to onnx C# ML Reasoning

Abhängigkeit: Installieren Sie Tesnsorflow 2.0, installieren Sie Python 3.7 oder höher, installieren Sie VSCode, Windows-Betriebssystem

1. Modellkonvertierung

1.1 Laden des Modells

Erstellen Sie ein VSCode-Projektverzeichnis und öffnen Sie den Ordner

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

Laden Sie das JSON-Modell und die Gewichtsdaten gemäß der Datei

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"])      

Dump-Modell

import tensorflow as tf

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

1.2 Durchführung der Konvertierung

pip install tf2onnx

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

1.3 model.onnx anzeigen

Laden Sie Netron herunter und installieren Sie es standardmäßig

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

Öffnen Sie die Modelldatei und zeigen Sie die erste Eingabe an

如:input_11

2. C#-Anwendung onnx

Installieren Sie Machine Learning Runtime-Nuget

Microsoft.ML.OnnxRuntime

Installieren Sie OpenCV-Pakete und -Abhängigkeiten

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

Grundlegende Erweiterungsfunktionen

/// <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;
}

Grundlegende Bildladefunktion

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;
        }
    }
}

Modellanwendungsfunktion (class

 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;
    }
 }

Unit-Test-Funktion

[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);
    }
}

Guess you like

Origin blog.csdn.net/black0707/article/details/128197819