Esempio n. 1
0
            private static Task <Tuple <long, TrainedNework_Simple> > TrainAsync(Tuple <string, EncogOCR_SketchData[]>[] sketches, long token, bool shouldGenerateGarbage, CancellationTokenSource cancel)
            {
                CancellationToken cancelToken = cancel.Token;

                return(Task.Run(() =>
                {
                    string[] outputMap = sketches.
                                         Select(o => o.Item1).
                                         ToArray();

                    int inputSize = sketches[0].Item2[0].NNInput.Length;

                    #region Training Data

                    List <double[]> inputs = new List <double[]>();
                    List <double[]> outputs = new List <double[]>();

                    int groupIndex = 0;
                    foreach (var group in sketches)
                    {
                        double[] output = Enumerable.Range(0, outputMap.Length).
                                          Select((o, i) => i == groupIndex ? 1d : 0d).
                                          ToArray();

                        foreach (var input in group.Item2)
                        {
                            inputs.Add(input.NNInput);
                            outputs.Add(output);
                        }

                        groupIndex++;
                    }

                    if (shouldGenerateGarbage)
                    {
                        GenerateGarbageData(sketches.SelectMany(o => o.Item2).ToArray(), outputMap.Length, inputs, outputs);
                    }

                    #endregion

                    //NOTE: If there is an exception, the network couldn't be trained
                    BasicNetwork network = null;
                    try
                    {
                        network = UtilityEncog.GetTrainedNetwork2(inputs.ToArray(), outputs.ToArray(), 20, 300, cancelToken).NetworkOrNull;
                    }
                    catch (Exception) { }

                    var returnProps = new TrainedNework_Simple()
                    {
                        InputSize = inputSize,
                        Outputs = outputMap,
                        Network = network,
                    };

                    return Tuple.Create(token, returnProps);
                }, cancelToken));
            }
Esempio n. 2
0
        private static Visual3D TestSamples_Draw(SketchSample[] sketches, double[] hues)
        {
            const double RADIUS    = .5;
            const double DOTRADIUS = .035;

            #region Materials

            SpecularMaterial specular = new SpecularMaterial(new SolidColorBrush(UtilityWPF.ColorFromHex("50FFFFFF")), 2);

            var material_Color = hues.Select(o =>
            {
                ColorHSV color = new ColorHSV(o, 75, 75);

                MaterialGroup material = new MaterialGroup();
                material.Children.Add(new DiffuseMaterial(new SolidColorBrush(color.ToRGB())));
                material.Children.Add(specular);

                return(new { Color = color, Material = material });
            }).ToArray();

            ColorHSV      color_Gray    = new ColorHSV(0, 0, 50);
            MaterialGroup material_Gray = new MaterialGroup();
            material_Gray.Children.Add(new DiffuseMaterial(new SolidColorBrush(color_Gray.ToRGB())));
            material_Gray.Children.Add(specular);

            #endregion

            Model3DGroup group = new Model3DGroup();

            foreach (SketchSample sketch in sketches)
            {
                int?matchIndex = UtilityEncog.IsMatch(sketch.NNOutput);

                Material material;
                if (matchIndex == null)
                {
                    sketch.IsMatch = false;
                    sketch.Color   = color_Gray;
                    material       = material_Gray;
                }
                else
                {
                    sketch.IsMatch = true;
                    sketch.Color   = material_Color[matchIndex.Value].Color;
                    material       = material_Color[matchIndex.Value].Material;
                }

                sketch.Position        = Math3D.GetRandomVector_Spherical(RADIUS).ToPoint();
                sketch.Translate_3DDot = new TranslateTransform3D(sketch.Position.ToVector());

                // Geometry Model
                GeometryModel3D geometry = new GeometryModel3D();
                geometry.Material     = material;
                geometry.BackMaterial = material;
                geometry.Geometry     = UtilityWPF.GetSphere_Ico(DOTRADIUS, 1, true);

                geometry.Transform = sketch.Translate_3DDot;

                group.Children.Add(geometry);
            }

            ModelVisual3D visual = new ModelVisual3D();
            visual.Content = group;
            return(visual);
        }
Esempio n. 3
0
        /// <summary>
        /// Nearly identical to the above method, but the 4 corner values are shifted a bit
        /// </summary>
        private void btnXORPosNeg2_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _trainingData = null;
                _results      = null;

                #region Training data

                int numDirtySteps;
                if (!int.TryParse(txtNumSteps2.Text, out numDirtySteps))
                {
                    MessageBox.Show("", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                double stepSize      = 1d / numDirtySteps;
                double otherStepSize = stepSize / 6d;

                List <double[]> trainingInput  = new List <double[]>();
                List <double[]> trainingOutput = new List <double[]>();

                // Good Values (pure)
                trainingInput.Add(new[] { 0d, 0d });
                trainingOutput.Add(new[] { -1d });

                trainingInput.Add(new[] { 1d, 0d });
                trainingOutput.Add(new[] { 1d });

                trainingInput.Add(new[] { 0d, 1d });
                trainingOutput.Add(new[] { 1d });

                trainingInput.Add(new[] { 1d, 1d });
                trainingOutput.Add(new[] { -1d });

                // Good Values (shifted)
                trainingInput.Add(new[] { otherStepSize, otherStepSize });
                trainingOutput.Add(new[] { -1d });

                trainingInput.Add(new[] { 1d - otherStepSize, otherStepSize });
                trainingOutput.Add(new[] { 1d });

                trainingInput.Add(new[] { otherStepSize, 1d - otherStepSize });
                trainingOutput.Add(new[] { 1d });

                trainingInput.Add(new[] { 1d - otherStepSize, 1d - otherStepSize });
                trainingOutput.Add(new[] { -1d });

                // Bad Values
                for (int cntr1 = 0; cntr1 <= numDirtySteps; cntr1++)
                {
                    double dirtyValue1 = cntr1 * stepSize;

                    for (int cntr2 = 0; cntr2 <= numDirtySteps; cntr2++)
                    {
                        if ((cntr1 == 0 || cntr1 == numDirtySteps) && (cntr2 == 0 || cntr2 == numDirtySteps))
                        {
                            continue;
                        }

                        double dirtyValue2 = cntr2 * stepSize;

                        trainingInput.Add(new[] { dirtyValue2, dirtyValue1 });
                        trainingOutput.Add(new[] { 0d });

                        trainingInput.Add(new[] { dirtyValue1, dirtyValue2 });
                        trainingOutput.Add(new[] { 0d });
                    }
                }

                _trainingData = GetDrawDataFromTrainingData(trainingInput.ToArray(), trainingOutput.ToArray());

                #endregion

                BasicNetwork network = UtilityEncog.GetTrainedNetwork(trainingInput.ToArray(), trainingOutput.ToArray(), maxSeconds_PerAttempt: MAXSECONDSPER, maxSeconds_Total: MAXSECONDSTOTAL).NetworkOrNull;

                #region Test

                //NOTE: I initially ran a bunch of tests, but the network always returns exactly the same result when given the same inputs
                //var test = Enumerable.Range(0, 1000).
                //    Select(o => new { In1 = _rand.Next(2), In2 = _rand.Next(2) }).

                var test = trainingInput.
                           Select(o => new { In1 = Convert.ToInt32(o[0]), In2 = Convert.ToInt32(o[1]) }).
                           Select(o => new
                {
                    o.In1,
                    o.In2,
                    Expected = XORPosNeg(o.In1, o.In2),
                    NN       = CallNN(network, o.In1, o.In2),
                }).
                           Select(o => new { o.In1, o.In2, o.Expected, o.NN, Error = Math.Abs(o.Expected - o.NN) }).
                           OrderByDescending(o => o.Error).
                           ToArray();

                #endregion
                #region Test intermediate values

                // It was only trained with inputs of 0 and 1.  Let's see what it does with values in between

                var intermediates = Enumerable.Range(0, 1000).
                                    Select(o => new { In1 = _rand.NextDouble(), In2 = _rand.NextDouble() }).
                                    Select(o => new
                {
                    o.In1,
                    o.In2,
                    NN = CallNN(network, o.In1, o.In2),
                }).
                                    //OrderBy(o => o.In1).
                                    //ThenBy(o => o.In2).
                                    OrderBy(o => o.NN).
                                    ToArray();

                #endregion

                #region Store results

                double[] matchValues = new[] { -1d, 1d };
                double   matchRange  = .06;     //+- 5% of target value would be considered a match

                _results = intermediates.
                           Select(o => Tuple.Create(new Point(o.In1, o.In2), o.NN, IsMatch(o.NN, matchValues, matchRange))).
                           ToArray();

                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally
            {
                RedrawResults();
            }
        }
Esempio n. 4
0
        private void RecognizeImage()
        {
            const string BORDER_STAND = "mildBorder";
            const string BORDER_FOUND = "validGuessBorder";

            lblCurrentGuess.Text  = "";
            pnlCurrentGuess.Style = (Style)this.Resources[BORDER_STAND];
            grdGuessDetails.Children.Clear();
            grdGuessDetails.RowDefinitions.Clear();

            if (_network == null || _currentSketch == null || _currentSketch.NNInput.Length != _network.InputSize)
            {
                return;
            }

            // Recognize
            double[] output = _network.Network.Compute(_currentSketch.NNInput);

            var allOutputs = output.
                             Select((o, i) => new { Value = o, Index = i, Name = _network.Outputs[i] }).
                             OrderByDescending(o => o.Value).
                             ToArray();

            #region Show results

            Brush percentStroke = new SolidColorBrush(UtilityWPF.ColorFromHex("60000000"));
            Brush percentFill   = new SolidColorBrush(UtilityWPF.ColorFromHex("30000000"));

            foreach (var outputEntry in allOutputs)
            {
                grdGuessDetails.RowDefinitions.Add(new RowDefinition()
                {
                    Height = new GridLength(1, GridUnitType.Auto)
                });

                // Name
                TextBlock outputText = new TextBlock()
                {
                    Text = outputEntry.Name,
                    HorizontalAlignment = HorizontalAlignment.Right,
                    VerticalAlignment   = VerticalAlignment.Center,
                };

                Grid.SetColumn(outputText, 0);
                Grid.SetRow(outputText, grdGuessDetails.RowDefinitions.Count - 1);

                grdGuessDetails.Children.Add(outputText);

                // % background
                Rectangle rectPerc = new Rectangle()
                {
                    Height = 20,
                    Width  = outputEntry.Value * 100,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Fill = percentFill,
                };

                Grid.SetColumn(rectPerc, 2);
                Grid.SetRow(rectPerc, grdGuessDetails.RowDefinitions.Count - 1);

                grdGuessDetails.Children.Add(rectPerc);

                // % border
                rectPerc = new Rectangle()
                {
                    Height = 20,
                    Width  = 100,
                    HorizontalAlignment = HorizontalAlignment.Left,
                    Stroke          = percentStroke,
                    StrokeThickness = 1,
                };

                Grid.SetColumn(rectPerc, 2);
                Grid.SetRow(rectPerc, grdGuessDetails.RowDefinitions.Count - 1);

                grdGuessDetails.Children.Add(rectPerc);

                // % text
                TextBlock outputPerc = new TextBlock()
                {
                    Text = Math.Round(outputEntry.Value * 100).ToString(),
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment   = VerticalAlignment.Center,
                };

                Grid.SetColumn(outputPerc, 2);
                Grid.SetRow(outputPerc, grdGuessDetails.RowDefinitions.Count - 1);

                grdGuessDetails.Children.Add(outputPerc);
            }

            #endregion

            #region Show final guess

            //int? matchIndex = UtilityEncog.IsMatch(allOutputs.Select(o => o.Value).ToArray());
            int?matchIndex = UtilityEncog.IsMatch(allOutputs.Select(o => o.Value).ToArray(), .4, .51);       // when using softmax, the threshold needs to be lower

            if (matchIndex != null)
            {
                lblCurrentGuess.Text  = allOutputs[matchIndex.Value].Name;
                pnlCurrentGuess.Style = (Style)this.Resources[BORDER_FOUND];
            }
            else
            {
                lblCurrentGuess.Text  = "";
                pnlCurrentGuess.Style = (Style)this.Resources[BORDER_STAND];
            }

            #endregion
        }
Esempio n. 5
0
        /// <summary>
        /// Call this if a new dot is added, or if the network gets swapped out
        /// NOTE: EnsureDotCreated needs to be called first
        /// </summary>
        private void ReconstructDot(Dot dot)
        {
            if (_dots == null)
            {
                return;
            }

            #region Remove Existing

            // Remove distances
            _dots.Distances_Input.RemoveAll(o => o.Item1.Token == dot.Token || o.Item2.Token == dot.Token);
            _dots.Distances_Output.RemoveAll(o => o.Item1.Token == dot.Token || o.Item2.Token == dot.Token);

            // Remove the 3D dot from visual
            if (dot.Geometry_3DDot != null)
            {
                _dots.ModelGroup.Children.Remove(dot.Geometry_3DDot);

                dot.Geometry_3DDot  = null;
                dot.Translate_3DDot = null;
            }

            // Remove the 2D visual
            dot.Image = null;

            #endregion

            if (_network == null || _networkInputs == null || _networkOutputs == null)
            {
                return;
            }

            #region Test against network

            if (dot.VectorSource != null)
            {
                // Make sure the input is correct
                dot.VectorSource.GenerateBitmap(_networkInputs.ImageHeightWidth);
                dot.NNInput = dot.VectorSource.NNInput;
            }

            if (dot.NNInput == null || dot.NNInput.Length != _networkInputs.Size)
            {
                return;
            }

            // Run it through the network
            dot.NNOutput = _network.Net.Network.Compute(dot.NNInput);

            #endregion

            #region Draw

            int?matchIndex = UtilityEncog.IsMatch(dot.NNOutput);

            // Material
            Material material;
            if (matchIndex == null)
            {
                dot.IsMatch = false;
                dot.Color   = _networkOutputs.ColorGray;
                material    = _networkOutputs.DotGray;
            }
            else
            {
                dot.IsMatch = true;
                dot.Color   = _networkOutputs.DotColors[matchIndex.Value].Item1;
                material    = _networkOutputs.DotColors[matchIndex.Value].Item2;
            }

            dot.Translate_3DDot = new TranslateTransform3D(dot.Position.ToVector());

            // Geometry
            dot.Geometry_3DDot = new GeometryModel3D()
            {
                Material     = material,
                BackMaterial = material,
                Geometry     = UtilityWPF.GetSphere_Ico(DOTRADIUS, 1, true),
                Transform    = dot.Translate_3DDot,
            };

            _dots.ModelGroup.Children.Add(dot.Geometry_3DDot);

            #endregion

            #region Distances

            var inputs  = new List <Tuple <Dot, Dot, double> >();
            var outputs = new List <Tuple <Dot, Dot, double> >();

            foreach (Dot other in _dots.Dots.Where(o => o.Token != dot.Token && o.NNInput != null && o.NNOutput != null))       // when the network gets reset, it sets all the dots' NNInput/Output to null.  Then goes through each dot and reconstructs.  So if I/O is null, it just hasn't been reconstructed yet
            {
                double distance = (dot.NNInput.ToVectorND() - other.NNInput.ToVectorND()).Length * _networkInputs.DistanceMult;
                inputs.Add(Tuple.Create(dot, other, distance));

                distance = (dot.NNOutput.ToVectorND() - other.NNOutput.ToVectorND()).Length * _networkOutputs.DistanceMult;
                outputs.Add(Tuple.Create(dot, other, distance));
            }

            _dots.Distances_Input.AddRange(inputs);
            _dots.Distances_Output.AddRange(outputs);

            #endregion
        }