private double CalculateErrorForRow(BackPropagationTrainingRow row)
 {
     var error = .0;
       for (var i = 0; i < row.Outputs.Length; i++)
       {
     var d = row.Outputs[i] - _network.OutputNodes[i].Value;
     error += d * d;
       }
       return Math.Sqrt(error);
 }
Пример #2
0
        private double CalculateErrorForRow(BackPropagationTrainingRow row)
        {
            var error = .0;

            for (var i = 0; i < row.Outputs.Length; i++)
            {
                var d = row.Outputs[i] - _network.OutputNodes[i].Value;
                error += d * d;
            }
            return(Math.Sqrt(error));
        }
Пример #3
0
        public MainViewModel()
        {
            InitNeuralNetwork();

            Text       = "Simple OCR";
            Rows       = Cols = 10;
            IsTraining = true;

            Cells   = Enumerable.Range(0, Rows * Cols).Select(_ => new CellViewModel()).ToList();
            Numbers = Enumerable.Range(0, 10).ToList();

            ResetCommmand = new ActionCommand(_ => Reset());
            OkCommmand    = new ActionCommand(_ =>
            {
                _network.Invalidate();
                if (IsTraining)
                {
                    var row = BackPropagationTrainingRow.Create(_network);
                    Cells.ForEach((i, c) => row.Inputs[i] = c.IsChecked ? 1 : 0);
                    for (var i = 0; i < 10; i++)
                    {
                        row.Outputs[i] = (SelectedNumber == i) ? 1.0 : 0.0;
                    }
                    _trainingRows.Add(row);
                }
                else
                {
                    // Feed input data to neural network.
                    Cells.ForEach((i, c) => _network.InputNodes[i++].Value = c.IsChecked ? 1 : 0);
                    // Find node with highest activation.
                    var node       = _network.OutputNodes.First(n => n.Value == _network.OutputNodes.Max(nn => nn.Value));
                    SelectedNumber = _network.OutputNodes.IndexOf(node);
                }
                Reset();
            });
        }
        private void UpdateWeights(double adjust, double momentum, BackPropagationTrainingRow row)
        {
            // Compute output gradients
              for (var i = 0; i < _outputGradients.Length; i++)
              {
            var output = _network.OutputNodes[i].Value;
            var derivative = (1 - output) * output; // derivative of log-sigmoid is y * (1 - y)
            _outputGradients[i] = derivative * (row.Outputs[i] - output); // gradient = (1 - O)(O) * (T-O)
              }

              // Compute hidden gradients
              for (var i = 0; i < _hiddenGradients.Length; i++)
              {
            var hidden = _network.HiddenNodes[i].Value;
            var derivative = (1 - hidden) * (1 + hidden); // derivative of tanh is (1 - y) * (1 + y)
            var sum = .0;
            for (var j = 0; j < _network.OutputNodes.Count; j++)
            {
              // each hidden delta is the sum of numOutput terms
              sum += _outputGradients[j] * _network.OutputNodes[j].Incoming[i].Weight; // each downstream gradient * outgoing weight
            }
            _hiddenGradients[i] = derivative * sum; // hGrad = (1-O)(1+O) * E(oGrads*oWts)
              }

              // Update input to hidden weights
              for (var i = 0; i < _network.InputNodes.Count; ++i)
              {
            for (var j = 0; j < _network.HiddenNodes.Count; ++j)
            {
              var delta = adjust * _hiddenGradients[j] * _network.InputNodes[i].Value; // compute the new delta = "eta * hGrad * input"
              _network.HiddenNodes[j].Incoming[i].Weight += delta; // update
              _network.HiddenNodes[j].Incoming[i].Weight += momentum * _network.HiddenNodes[j].Incoming[i].Delta; // add momentum using previous delta. on first pass old value will be 0.0 but that's OK.
              _network.HiddenNodes[j].Incoming[i].Delta = delta; // save the delta for next time
            }
              }

              // Update hidden biases
              for (var i = 0; i < _network.HiddenNodes.Count; ++i)
              {
            var delta = adjust * _hiddenGradients[i];
            _network.HiddenNodes[i].Bias += delta;
            _network.HiddenNodes[i].Bias += momentum * _network.HiddenNodes[i].BiasDelta;
            _network.HiddenNodes[i].BiasDelta = delta; // save delta
              }

              // Update hidden to output weights
              for (var i = 0; i < _network.HiddenNodes.Count; i++)
              {
            for (var j = 0; j < _network.OutputNodes.Count; ++j)
            {
              var delta = adjust * _outputGradients[j] * _network.HiddenNodes[i].Value;
              _network.OutputNodes[j].Incoming[i].Weight += delta;
              _network.OutputNodes[j].Incoming[i].Weight += momentum * _network.OutputNodes[j].Incoming[i].Delta;
              _network.OutputNodes[j].Incoming[i].Delta = delta;
            }
              }

              // Update hidden to output biases
              for (var i = 0; i < _network.OutputNodes.Count; i++)
              {
            var delta = adjust * _outputGradients[i];
            _network.OutputNodes[i].Bias += delta;
            _network.OutputNodes[i].Bias += momentum * _network.OutputNodes[i].BiasDelta;
            _network.OutputNodes[i].BiasDelta = delta;
              }
        }
Пример #5
0
        private void UpdateWeights(double adjust, double momentum, BackPropagationTrainingRow row)
        {
            // Compute output gradients
            for (var i = 0; i < _outputGradients.Length; i++)
            {
                var output     = _network.OutputNodes[i].Value;
                var derivative = (1 - output) * output;                       // derivative of log-sigmoid is y * (1 - y)
                _outputGradients[i] = derivative * (row.Outputs[i] - output); // gradient = (1 - O)(O) * (T-O)
            }

            // Compute hidden gradients
            for (var i = 0; i < _hiddenGradients.Length; i++)
            {
                var hidden     = _network.HiddenNodes[i].Value;
                var derivative = (1 - hidden) * (1 + hidden); // derivative of tanh is (1 - y) * (1 + y)
                var sum        = .0;
                for (var j = 0; j < _network.OutputNodes.Count; j++)
                {
                    // each hidden delta is the sum of numOutput terms
                    sum += _outputGradients[j] * _network.OutputNodes[j].Incoming[i].Weight; // each downstream gradient * outgoing weight
                }
                _hiddenGradients[i] = derivative * sum;                                      // hGrad = (1-O)(1+O) * E(oGrads*oWts)
            }

            // Update input to hidden weights
            for (var i = 0; i < _network.InputNodes.Count; ++i)
            {
                for (var j = 0; j < _network.HiddenNodes.Count; ++j)
                {
                    var delta = adjust * _hiddenGradients[j] * _network.InputNodes[i].Value;                            // compute the new delta = "eta * hGrad * input"
                    _network.HiddenNodes[j].Incoming[i].Weight += delta;                                                // update
                    _network.HiddenNodes[j].Incoming[i].Weight += momentum * _network.HiddenNodes[j].Incoming[i].Delta; // add momentum using previous delta. on first pass old value will be 0.0 but that's OK.
                    _network.HiddenNodes[j].Incoming[i].Delta   = delta;                                                // save the delta for next time
                }
            }

            // Update hidden biases
            for (var i = 0; i < _network.HiddenNodes.Count; ++i)
            {
                var delta = adjust * _hiddenGradients[i];
                _network.HiddenNodes[i].Bias     += delta;
                _network.HiddenNodes[i].Bias     += momentum * _network.HiddenNodes[i].BiasDelta;
                _network.HiddenNodes[i].BiasDelta = delta; // save delta
            }

            // Update hidden to output weights
            for (var i = 0; i < _network.HiddenNodes.Count; i++)
            {
                for (var j = 0; j < _network.OutputNodes.Count; ++j)
                {
                    var delta = adjust * _outputGradients[j] * _network.HiddenNodes[i].Value;
                    _network.OutputNodes[j].Incoming[i].Weight += delta;
                    _network.OutputNodes[j].Incoming[i].Weight += momentum * _network.OutputNodes[j].Incoming[i].Delta;
                    _network.OutputNodes[j].Incoming[i].Delta   = delta;
                }
            }

            // Update hidden to output biases
            for (var i = 0; i < _network.OutputNodes.Count; i++)
            {
                var delta = adjust * _outputGradients[i];
                _network.OutputNodes[i].Bias     += delta;
                _network.OutputNodes[i].Bias     += momentum * _network.OutputNodes[i].BiasDelta;
                _network.OutputNodes[i].BiasDelta = delta;
            }
        }