Пример #1
0
        private void BackPropagationOutput(int row)
        {
            int lastLayerNeurons    = _layers[_layers.Length - 1].Neurons.Length;
            int connectionsToNeuron = _layers[_layers.Length - 1].Neurons[0].Synapses.Length;

            // Operowanie na każdym neuronie w ostaniej warstwie
            for (int i = 0; i < lastLayerNeurons; i++)
            {
                // output - ExpectedOutput
                // Pochodna po funkcji kosztu
                double difference = (_layers[_layers.Length - 1].Neurons[i].Value - _expectedResults[row][i]);

                // SigmoidDerivative to pochodna po funkcji aktywacji z neurona
                double nodeDelta = difference * MathFuncs.SigmoidDerivative(_layers[_layers.Length - 1].Neurons[i].Value);
                _layers[_layers.Length - 1].Neurons[i].PreviousPartialDerivative = nodeDelta;

                // Dla każdego neurona z ostatniej warstwy obsługiwanie jednej z jego synaps wejściowych
                for (int j = 0; j < connectionsToNeuron; j++)
                {
                    // Wartości neuronów z poprzedniej warstwy
                    double netInput = _layers[_layers.Length - 2].Neurons[j].Value;
                    double delta    = -1 * nodeDelta * netInput;

                    // Aktualizacja wagi
                    // Wcześniejsza waga wpisywana na previousWeight, potrzebne do dalszej propagacji, ponieważ
                    // to ją będziemy uwzględniać ( w Weight będzie waga zaaktualizowana )
                    _layers[_layers.Length - 1].Neurons[i].Synapses[j].PreviousWeight = _layers[_layers.Length - 1].Neurons[i].Synapses[j].Weight;
                    _layers[_layers.Length - 1].Neurons[i].Synapses[j].Weight        += (delta * _learningRate);
                }
            }
        }
Пример #2
0
        private void BackPropagationHidden()
        {
            // Iterowanie po warstwach wstecz, od przedostatniej warstwy
            // stop przy drugiej warstwie
            for (int i = _layers.Length - 2; i > 0; i--)
            {
                // Iterowanie po neuronach w warstwie
                for (int j = 0; j < _layers[i].Neurons.Length; j++)
                {
                    // Iterowanie po wejściowych synapsach neuronu
                    // Przygotowanie do aktualizacji ich wag
                    for (int k = 0; k < _layers[i].Neurons[j].Synapses.Length; k++)
                    {
                        // Poprzednia wartość neurona
                        double netInput   = _layers[i - 1].Neurons[k].Value;
                        double sumPartial = 0;
                        // Iteracja po neuronach z warstwy następnej ( poprzedniej patrząc na propagacje
                        // jako na iteracje od końca do początku)
                        // Zbieranie wag i poprzednich pochodnych z wcześniejszych połączeń
                        for (int m = 0; m < _layers[i + 1].Neurons.Length; m++)
                        {
                            sumPartial += _layers[i + 1].Neurons[m].Synapses[j].PreviousWeight * _layers[i + 1].Neurons[m].PreviousPartialDerivative;
                        }

                        // Pochodna obecnej warstwy
                        double nodeDelta = sumPartial * MathFuncs.SigmoidDerivative(_layers[i].Neurons[j].Value);
                        _layers[i].Neurons[j].PreviousPartialDerivative = nodeDelta;

                        double delta = -1 * netInput * nodeDelta;

                        // Aktualizacja wagi
                        // Wcześniejsza waga wpisywana na previousWeight, potrzebne do dalszej propagacji, ponieważ
                        // to ją będziemy uwzględniać ( w Weight będzie waga zaaktualizowana )
                        _layers[i].Neurons[j].Synapses[k].PreviousWeight = _layers[i].Neurons[j].Synapses[k].Weight;
                        _layers[i].Neurons[j].Synapses[k].Weight        += (delta * _learningRate);
                    }
                }
            }
        }