using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using SixLabors.ImageSharp; using ZeroLevel.NN.Models; namespace ZeroLevel.NN { public abstract class SSDNN : IDisposable { private readonly InferenceSession _session; public SSDNN(string modelPath, bool gpu = false) { if (gpu) { try { var so = SessionOptions.MakeSessionOptionWithCudaProvider(0); so.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_VERBOSE; so.GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL; _session = new InferenceSession(modelPath, so); } catch (Exception ex) { Log.Error(ex, "Fault create InferenceSession with CUDA"); _session = new InferenceSession(modelPath); } } else { _session = new InferenceSession(modelPath); } } protected void Extract(IDictionary> input, Action>> inputHandler) { var container = new List(); foreach (var pair in input) { container.Add(NamedOnnxValue.CreateFromTensor(pair.Key, pair.Value)); } using (var output = _session.Run(container)) { var result = new Dictionary>(); foreach (var o in output) { result.Add(o.Name, o.AsTensor()); } inputHandler.Invoke(result); } } /// /// Scale input vectors individually to unit norm (vector length). /// protected void Norm(float[] vector) { var totalSum = vector.Sum(v => v * v); var length = (float)Math.Sqrt(totalSum); var inverseLength = 1.0f / length; for (int i = 0; i < vector.Length; i++) { vector[i] *= inverseLength; } } protected ImagePredictionInput[] MakeInputBatch(Image image, ImagePreprocessorOptions options) { return ImagePreprocessor.ToTensors(image, options); } protected Tensor MakeInput(Image image, ImagePreprocessorOptions options) { var input = ImagePreprocessor.ToTensors(image, options); return input[0].Tensor; } protected int Argmax(float[] embedding) { if (embedding.Length == 0) return -1; var im = 0; var max = embedding[0]; for (var i = 1; i < embedding.Length; i++) { if (embedding[i] > max) { im = i; max = embedding[i]; } } return im; } public void Dispose() { _session?.Dispose(); } } }