From b82fa900332cb64ab5a1479e5245682e85ac47b1 Mon Sep 17 00:00:00 2001 From: Ogoun Date: Fri, 1 Apr 2022 18:53:13 +0300 Subject: [PATCH] Update 1. ZeroLevel Fix configuration floating numbers convert 2. Append GoogleAgeDetector to ZeroLevel.NN --- .../AgeDetectors/GoogleAgeDetector.cs | 55 +++++++++++++++++++ .../Architectures/FaceRecognition/Resnet27.cs | 40 ++++++++++++++ ZeroLevel.NN/ZeroLevel.NN.csproj | 3 +- ZeroLevel.UnitTests/ConfigurationTest.cs | 22 ++++++++ .../Services/Config/BaseConfiguration.cs | 6 ++ .../Services/DOM/DSL/Services/TContainer.cs | 1 + .../Reflection/StringToTypeConverter.cs | 7 +++ ZeroLevel/Services/Reflection/TypeHelpers.cs | 13 +++++ ZeroLevel/ZeroLevel.csproj | 10 ++-- 9 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 ZeroLevel.NN/Architectures/AgeDetectors/GoogleAgeDetector.cs create mode 100644 ZeroLevel.NN/Architectures/FaceRecognition/Resnet27.cs diff --git a/ZeroLevel.NN/Architectures/AgeDetectors/GoogleAgeDetector.cs b/ZeroLevel.NN/Architectures/AgeDetectors/GoogleAgeDetector.cs new file mode 100644 index 0000000..04f0d38 --- /dev/null +++ b/ZeroLevel.NN/Architectures/AgeDetectors/GoogleAgeDetector.cs @@ -0,0 +1,55 @@ +using Microsoft.ML.OnnxRuntime.Tensors; +using SixLabors.ImageSharp; +using ZeroLevel.NN.Models; + +namespace ZeroLevel.NN +{ + public enum Age + { + From0To2, + From4To6, + From8To12, + From15To20, + From25To32, + From38To43, + From48To53, + From60To100 + } + + /// + /// Input tensor is 1 x 3 x height x width with mean values 104, 117, 123. Input image have to be previously resized to 224 x 224 pixels and converted to BGR format. + /// + public class GoogleAgeDetector + : SSDNN + { + private const int INPUT_WIDTH = 224; + private const int INPUT_HEIGHT = 224; + private static float[] MEAN = new[] { 104f, 117f, 123f }; + + private Age[] _ageList = new[] { Age.From0To2, Age.From4To6, Age.From8To12, Age.From15To20, Age.From25To32, Age.From38To43, Age.From48To53, Age.From60To100 }; + + public GoogleAgeDetector(string modelPath, bool gpu = false) : base(modelPath, gpu) + { + } + + public Age Predict(Image image) + { + var input = MakeInput(image, + new ImagePreprocessorOptions(INPUT_WIDTH, INPUT_HEIGHT, PredictorChannelType.ChannelFirst) + .ApplyCorrection((c, px) => px - MEAN[c]) + .ApplyAxeInversion()); + return Predict(input); + } + + public Age Predict(Tensor input) + { + float[] variances = null; + Extract(new Dictionary> { { "input", input } }, d => + { + variances = d.First().Value.ToArray(); + }); + var (number, index) = variances.Select((n, i) => (n, i)).Max(); + return _ageList[index]; + } + } +} diff --git a/ZeroLevel.NN/Architectures/FaceRecognition/Resnet27.cs b/ZeroLevel.NN/Architectures/FaceRecognition/Resnet27.cs new file mode 100644 index 0000000..01c6d6b --- /dev/null +++ b/ZeroLevel.NN/Architectures/FaceRecognition/Resnet27.cs @@ -0,0 +1,40 @@ +using Microsoft.ML.OnnxRuntime.Tensors; +using SixLabors.ImageSharp; +using ZeroLevel.NN.Models; + +namespace ZeroLevel.NN +{ + public class Resnet27 + : SSDNN, IEncoder + { + private const int INPUT_WIDTH = 128; + private const int INPUT_HEIGHT = 128; + public Resnet27(string modelPath) + : base(modelPath) + { + } + + public int InputW => INPUT_WIDTH; + public int InputH => INPUT_HEIGHT; + + public float[] Predict(Image image) + { + var input = MakeInput(image, + new ImagePreprocessorOptions(INPUT_WIDTH, INPUT_HEIGHT, PredictorChannelType.ChannelFirst) + .ApplyCorrection((c, px) => (px - 127.5f) / 128f) + .ApplyAxeInversion()); + return Predict(input); + } + + public float[] Predict(Tensor input) + { + float[] embedding = null; + Extract(new Dictionary> { { "input.1", input } }, d => + { + embedding = d.First().Value.ToArray(); + }); + Norm(embedding); + return embedding; + } + } +} diff --git a/ZeroLevel.NN/ZeroLevel.NN.csproj b/ZeroLevel.NN/ZeroLevel.NN.csproj index d2c9be4..055fdc2 100644 --- a/ZeroLevel.NN/ZeroLevel.NN.csproj +++ b/ZeroLevel.NN/ZeroLevel.NN.csproj @@ -7,7 +7,7 @@ True embedded none - 1.0.0.0 + 1.0.0.1 Ogoun Ogoun Copyright Ogoun 2022 @@ -15,6 +15,7 @@ https://github.com/ogoun/Zero/wiki https://github.com/ogoun/Zero git + New architectures diff --git a/ZeroLevel.UnitTests/ConfigurationTest.cs b/ZeroLevel.UnitTests/ConfigurationTest.cs index 14da601..ea5fd72 100644 --- a/ZeroLevel.UnitTests/ConfigurationTest.cs +++ b/ZeroLevel.UnitTests/ConfigurationTest.cs @@ -73,5 +73,27 @@ namespace ZeroLevel.UnitTests Assert.Equal("System", config.Service.ServiceGroup); Assert.Equal("service", config.Service.ServiceType); } + + [Fact] + public void NumbersTest() + { + // Arrange + var set = Configuration.CreateSet(); + var d = 0.27; + var f = 0.5f; + var i = 12; + + // Act + set.Default.Append("d", "0.27"); + set.Default.Append("f", "0.5"); + set.Default.Append("i", "12"); + + var td = set.Default.First("d"); + + // Assert + Assert.Equal(d, td); + Assert.Equal(f, set.Default.First("f")); + Assert.Equal(i, set.Default.First("i")); + } } } diff --git a/ZeroLevel/Services/Config/BaseConfiguration.cs b/ZeroLevel/Services/Config/BaseConfiguration.cs index a911911..e7bd8f8 100644 --- a/ZeroLevel/Services/Config/BaseConfiguration.cs +++ b/ZeroLevel/Services/Config/BaseConfiguration.cs @@ -150,7 +150,9 @@ namespace ZeroLevel.Services.Config if (_keyValues.TryGetValue(GetKey(key), out result)) { if (result.Count > 0) + { return (T)StringToTypeConverter.TryConvert(result[0], typeof(T)); + } return default(T); } throw new KeyNotFoundException("Parameter not found: " + key); @@ -185,7 +187,9 @@ namespace ZeroLevel.Services.Config if (_keyValues.TryGetValue(GetKey(key), out result)) { if (result.Count > 0) + { return (T)StringToTypeConverter.TryConvert(result[0], typeof(T)); + } } return default(T); } @@ -203,7 +207,9 @@ namespace ZeroLevel.Services.Config if (_keyValues.TryGetValue(GetKey(key), out result)) { if (result.Count > 0) + { return (T)StringToTypeConverter.TryConvert(result[0], typeof(T)); + } } return defaultValue; } diff --git a/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs b/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs index b3594c3..1118fd4 100644 --- a/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs +++ b/ZeroLevel/Services/DOM/DSL/Services/TContainer.cs @@ -2707,6 +2707,7 @@ namespace DOM.DSL.Services private static object ConvertTo(string line, Type type) { return StringToTypeConverter.TryConvert(line, type); + } #endregion Conditions diff --git a/ZeroLevel/Services/Reflection/StringToTypeConverter.cs b/ZeroLevel/Services/Reflection/StringToTypeConverter.cs index 8f38139..fdce165 100644 --- a/ZeroLevel/Services/Reflection/StringToTypeConverter.cs +++ b/ZeroLevel/Services/Reflection/StringToTypeConverter.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using System.Globalization; namespace ZeroLevel.Services.Reflection { @@ -14,6 +15,12 @@ namespace ZeroLevel.Services.Reflection { try { + if (TypeHelpers.IsNumericTypeWithFloating(to)) + { + input = input. + Replace(",", CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator). + Replace(".", CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator); + } return TypeDescriptor.GetConverter(to).ConvertFromString(input); } catch diff --git a/ZeroLevel/Services/Reflection/TypeHelpers.cs b/ZeroLevel/Services/Reflection/TypeHelpers.cs index 929f639..87625b2 100644 --- a/ZeroLevel/Services/Reflection/TypeHelpers.cs +++ b/ZeroLevel/Services/Reflection/TypeHelpers.cs @@ -49,6 +49,19 @@ namespace ZeroLevel.Services.Reflection } } + public static bool IsNumericTypeWithFloating(Type type) + { + switch (Type.GetTypeCode(type)) + { + case TypeCode.Decimal: + case TypeCode.Double: + case TypeCode.Single: + return true; + default: + return false; + } + } + public static bool IsEnum(Type type) { return type.Return(t => t.IsEnum, false); diff --git a/ZeroLevel/ZeroLevel.csproj b/ZeroLevel/ZeroLevel.csproj index cd57871..8ca8510 100644 --- a/ZeroLevel/ZeroLevel.csproj +++ b/ZeroLevel/ZeroLevel.csproj @@ -6,19 +6,19 @@ ogoun ogoun - 3.3.6.2 - Update distance metrics + 3.3.6.3 + Configuration floating number convert fix https://github.com/ogoun/Zero/wiki Copyright Ogoun 2022 https://github.com/ogoun/Zero git - 3.3.6.2 - 3.3.6.2 + 3.3.6.3 + 3.3.6.3 AnyCPU;x64;x86 zero.png - none + full none zero.ico AnyCPU