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