public void FromImageTest_1bpp() { foreach (string format in new string[] { Shape.BWHC, Shape.BHWC, Shape.BCHW }) { Image image = new Image(53, 67, 1, 200, 200); image.Randomize(); Tensor tensor = ImageExtensions.FromImage(image, null, format, image.Width, image.Height); Assert.AreEqual(format, tensor.Shape.Format); Assert.AreEqual(1, tensor.Shape.GetAxis(Axis.B)); Assert.AreEqual(53, tensor.Shape.GetAxis(Axis.X)); Assert.AreEqual(53, tensor.Shape.GetAxis(Axis.X)); Assert.AreEqual(1, tensor.Shape.GetAxis(Axis.C)); for (int x = 0; x < image.Width; x++) { for (int y = 0; y < image.Height; y++) { float expected = image.GetPixel(x, y); Assert.AreEqual(expected, tensor[tensor.Shape.Position(0, x, y, 0)], 1e-6f); } } } }
public void FromImageTest_24to32bpp() { foreach (int bpp in new int[] { 24, 32 }) { foreach (string format in new string[] { Shape.BWHC, Shape.BHWC, Shape.BCHW }) { Image image = new Image(53, 67, bpp, 200, 200); image.Randomize(); Tensor tensor = ImageExtensions.FromImage(image, null, format, image.Width, image.Height); Assert.AreEqual(format, tensor.Shape.Format); Assert.AreEqual(1, tensor.Shape.GetAxis(Axis.B)); Assert.AreEqual(53, tensor.Shape.GetAxis(Axis.X)); Assert.AreEqual(53, tensor.Shape.GetAxis(Axis.X)); Assert.AreEqual(3, tensor.Shape.GetAxis(Axis.C)); for (int x = 0; x < image.Width; x++) { for (int y = 0; y < image.Height; y++) { Color color = Color.FromArgb(image.GetPixel(x, y)); float expected1 = (255.0f - color.B) / 255.0f; Assert.AreEqual(expected1, tensor[tensor.Shape.Position(0, x, y, 0)], 1e-6f); float expected2 = (255.0f - color.G) / 255.0f; Assert.AreEqual(expected2, tensor[tensor.Shape.Position(0, x, y, 1)], 1e-6f); float expected3 = (255.0f - color.R) / 255.0f; Assert.AreEqual(expected3, tensor[tensor.Shape.Position(0, x, y, 2)], 1e-6f); } } } } }
/// <inheritdoc /> /// <exception cref="ArgumentNullException"> /// <paramref name="source"/> is <b>null</b>. /// </exception> public Answer Recognize(ImageSource source, CancellationToken cancellationToken) { if (source == null) { throw new ArgumentNullException(nameof(source)); } // create input tensor Tensor x = ImageExtensions.FromImage( source.Image, "checkbox", this.network.InputShape.Format, this.network.InputShape.GetAxis(Axis.X), this.network.InputShape.GetAxis(Axis.Y)); // recognize the image IList <(string Answer, float Probability)> result = this.network.Execute(x).Answers[0]; // create the answer return(CheckboxReader.CreateAnswer(source, result)); }
private void Test() { ClassificationNetwork network = ClassificationNetwork.FromFile(this.options.NetworkFileName); List <ClassificationResult <string> > results = new List <ClassificationResult <string> >(); using (TestImageProvider <string> dataProvider = this.options.CreateTestImageProvider(network)) { ////Context model = Context.FromRegex(@"\d{1,5}", CultureInfo.InvariantCulture); ////int n = 0; foreach (TestImage sample in dataProvider.Generate(network.AllowedClasses)) { Interlocked.Increment(ref this.totalImages); ////sample.Image.Save("e:\\temp\\" + sample.Label + "_" + n.ToString(CultureInfo.InvariantCulture) + ".bmp"); ////n++; ////if (n < 171) continue; this.localTimeCounter.Restart(); Tensor x = ImageExtensions.FromImage( sample.Image, null, Shape.BWHC, network.InputShape.GetAxis(Axis.X), network.InputShape.GetAxis(Axis.Y)); IList <IList <(string Answer, float Probability)> > answers = network.Execute(x).Answers; ////(IList<(string Answer, float Probability)> answers, _) = network.ExecuteSequence(x, model); this.localTimeCounter.Stop(); long duration = this.localTimeCounter.ElapsedMilliseconds; foreach (IList <(string answer, float probability)> answer in answers) { string text = answer.FirstOrDefault().answer; float prob = answer.FirstOrDefault().probability; results.Add(new ClassificationResult <string>( sample.SourceId, text, string.Concat(sample.Labels), prob, prob >= 0.38f)); this.WriteLine( null, "({0})\tFile: {1} ... OK ({2} ms) {3} {4:F4}", this.totalImages, sample.SourceId.ToFileName(false), duration, text, prob); } /*string answer = answers.Last().FirstOrDefault()?.Answer; * int prob = (int)(((answers.Last().FirstOrDefault()?.Probability ?? 0.0f) * 100) + 0.5f); * * results.Add(new ClassificationResult<string>( * sample.SourceId, * answer, * string.Concat(sample.Labels), * prob, * prob >= 0.38f)); * * ////this.Write("."); * this.Write( * null, * "({0})\tFile: {1} ... OK ({4} ms) {2} {3:F4}", * this.totalImages, * sample.SourceId.ToFileName(false), * duration, * answer, * prob);*/ } } // write report ClassificationReport <string> testReport = new ClassificationReport <string>(results); using (StreamWriter outputFile = File.CreateText(this.options.OutputFileName)) { ClassificationReportWriter <string> .WriteReport(outputFile, testReport, ClassificationReportMode.All); } }
private void Learn(int taskIndex, LearningTask task, CancellationToken cancellationToken) { using (StreamWriter logFile = File.CreateText(task.LogFileName)) { logFile.AutoFlush = true; try { // report starting time DateTime dateStarted = DateTime.Now; this.WriteLine(logFile, string.Format(CultureInfo.InvariantCulture, "Started: {0}", dateStarted.ToString("G", CultureInfo.InvariantCulture))); ClassificationNetwork net = File.Exists(task.Architecture) ? ClassificationNetwork.FromFile(task.Architecture) : ClassificationNetwork.FromArchitecture(task.Architecture, task.Classes, task.Classes, task.BlankClass); // learning Learn(); net.SaveToFile(task.OutputFileName, NetworkFileFormat.JSON); // report finish time and processing interval DateTime dateFinished = DateTime.Now; this.WriteLine(logFile, string.Empty); this.WriteLine(logFile, string.Format(CultureInfo.InvariantCulture, "Finished: {0:G}", dateFinished)); this.WriteLine(logFile, string.Format(CultureInfo.InvariantCulture, "Total time: {0:g}", TimeSpan.FromSeconds((dateFinished - dateStarted).TotalSeconds))); void Learn() { this.WriteLine(logFile, "Learning..."); ImageDistortion filter = new ImageDistortion(); Stopwatch timer = new Stopwatch(); this.WriteLine(logFile, " Epochs: {0}", task.Epochs); this.WriteTrainerParameters(logFile, task.Trainer, task.Algorithm, task.Loss); this.WriteLine(logFile, "Image distortion:"); this.WriteLine(logFile, " Shift: {0}", task.Shift); this.WriteLine(logFile, " Rotate: {0}", task.Rotate); this.WriteLine(logFile, " Scale: {0}", task.Scale); this.WriteLine(logFile, " Crop: {0}", task.Crop); Shape shape = net.InputShape; using (TestImageProvider <string> dataProvider = task.CreateDataProvider(net)) { using (TestImageProvider <string> testDataProvider = task.CreateTestDataProvider(net)) { ////int n = 0; for (int epoch = 0; epoch < task.Epochs; epoch++) { // run learning timer.Restart(); TrainingResult result = task.Trainer.RunEpoch( epoch, net, GenerateLearnSamples(dataProvider, epoch), task.Algorithm, task.Loss, cancellationToken); timer.Stop(); lock (this.logLocker) { string s = string.Format( CultureInfo.InvariantCulture, "Net: {0}, Epoch: {1}, Time: {2} ms, {3}", taskIndex, epoch, timer.ElapsedMilliseconds, result); this.Write(logFile, s); ////this.WriteDebugInformation(logFile); this.WriteLine(logFile, string.Empty); } // run testing string epochOutputFileName = string.Format(CultureInfo.InvariantCulture, task.EpochFileNameTemplate, epoch); // save network net.SaveToFile(epochOutputFileName, NetworkFileFormat.JSON); // run testing List <ClassificationResult <string> > results = new List <ClassificationResult <string> >(); if (task.Loss is CTCLoss) { Context model = Context.FromRegex(@"\d", CultureInfo.InvariantCulture); foreach ((TestImage image, string[] labels) in GenerateTestSamples(testDataProvider)) { if (image.Image.IsAllWhite()) { results.Add(new ClassificationResult <string>( image.SourceId, "0", string.Concat(labels), 1.0f, true)); } else { Tensor x = ImageExtensions.FromImage(image.Image, null, Shape.BWHC, shape.GetAxis(Axis.X), shape.GetAxis(Axis.Y)); (string text, float prob) = net.ExecuteSequence(x, model).Answers.FirstOrDefault(); results.Add(new ClassificationResult <string>( image.SourceId, text, string.Concat(labels), prob, prob >= 0.38f)); } } } else { foreach ((TestImage image, string[] labels) in GenerateTestSamples(testDataProvider)) { if (image.Image.IsAllWhite()) { results.Add(new ClassificationResult <string>( image.SourceId, "0", string.Concat(labels), 1.0f, true)); } else { Tensor x = ImageExtensions.FromImage(image.Image, null, Shape.BWHC, shape.GetAxis(Axis.X), shape.GetAxis(Axis.Y)); foreach (IList <(string answer, float probability)> answer in net.Execute(x).Answers) { string text = answer.FirstOrDefault().answer; float prob = answer.FirstOrDefault().probability; results.Add(new ClassificationResult <string>( image.SourceId, text, string.Concat(labels), prob, prob >= 0.38f)); } } } } // write report ClassificationReport <string> testReport = new ClassificationReport <string>(results); this.Write(logFile, ClassificationReportWriter <string> .WriteReport(testReport, ClassificationReportMode.Summary)); using (StreamWriter outputFile = File.CreateText(Path.ChangeExtension(epochOutputFileName, ".res"))) { ClassificationReportWriter <string> .WriteReport(outputFile, testReport, ClassificationReportMode.All); } } } IEnumerable <(Tensor x, string[] labels)> GenerateLearnSamples(TestImageProvider <string> provider, int epoch) { return(GenerateSamples(provider) .Where(x => !x.image.Image.IsAllWhite()) .SelectMany(x => { if (epoch == 0) { ////x.Image.Save("e:\\temp\\" + x.Id + "_" + n.ToString(CultureInfo.InvariantCulture) + "_.bmp"); } return filter .Distort( x.image.Image, shape.GetAxis(Axis.X), shape.GetAxis(Axis.Y), task.Shift, task.Rotate && x.image.FontStyle != FontStyle.Italic, task.Scale, task.Crop) .Select(bitmap => { if (epoch == 0) { ////Interlocked.Increment(ref n); ////bitmap.Save(@"d:\dnn\temp\" + n.ToString(CultureInfo.InvariantCulture) + ".bmp"); ////bitmap.Save(@"d:\dnn\temp\" + (n).ToString(CultureInfo.InvariantCulture) + "_" + x.SourceId.Id + ".bmp"); } return (ImageExtensions.FromImage(bitmap, null, Shape.BWHC, shape.GetAxis(Axis.X), shape.GetAxis(Axis.Y)), x.labels); }); })); } IEnumerable <(TestImage image, string[] labels)> GenerateTestSamples(TestImageProvider <string> provider) { return(GenerateSamples(provider) .AsParallel() .AsOrdered() .WithCancellation(cancellationToken) .WithMergeOptions(ParallelMergeOptions.AutoBuffered)); } IEnumerable <(TestImage image, string[] labels)> GenerateSamples(TestImageProvider <string> provider) { return(provider .Generate(net.AllowedClasses) .Select(x => { string[] labels = x.Labels; if (!(task.Loss is CTCLoss)) { int b = net.OutputShapes.First().GetAxis(Axis.B); if (labels.Length == 1 && b > 1) { labels = Enumerable.Repeat(labels[0], b).ToArray(); } } return (x, labels); })); } } } } finally { logFile.Flush(); } } }