コード例 #1
0
        // Функція навчання
        public double Train(ref double[] input, ref double[] desired, double TrainingRate, double Momentum)
        {
            // Перевірка вхідних параметрів
            if (input.Length != inputSize)
            {
                throw new ArgumentException("Invalid input parameter", "input");
            }

            if (desired.Length != layerSize[layerCount - 1])
            {
                throw new ArgumentException("Invalid input parameter", "desired");
            }

            // Локальні змінні
            double error = 0.0, sum = 0.0, weigtdelta = 0.0, biasDelta = 0.0;

            double[] output = new double[layerSize[layerCount - 1]];

            // Запуск мережі
            Run(ref input, out output);

            //Розмножуємо похибку у зворотньму порядку
            for (int l = layerCount - 1; l >= 0; l--)
            {
                //Вихідний шар
                if (l == layerCount - 1)
                {
                    for (int k = 0; k < layerSize[l]; k++)
                    {
                        delta[l][k]  = output[k] - desired[k];
                        error       += Math.Pow(delta[l][k], 2);
                        delta[l][k] *= TransferFunctions.DerivativeEvaluate(transferFunction[l], layerInput[l][k]);
                    }
                }
                //Прихований шар
                else
                {
                    for (int i = 0; i < layerSize[l]; i++)
                    {
                        sum = 0.0;
                        for (int j = 0; j < layerSize[l + 1]; j++)
                        {
                            sum += weight[l + 1][i][j] * delta[l + 1][j];
                        }
                        sum        *= TransferFunctions.DerivativeEvaluate(transferFunction[l], layerInput[l][i]);
                        delta[l][i] = sum;
                    }
                }
            }

            // Оновлення ваг та відхилень
            for (int l = 0; l < layerCount; l++)
            {
                for (int i = 0; i < (l == 0 ? inputSize : layerSize[l - 1]); i++)
                {
                    for (int j = 0; j < layerSize[l]; j++)
                    {
                        weigtdelta       = TrainingRate * delta[l][j] * (l == 0 ? input[i] : layerOtput[l - 1][i]) + Momentum * previousWeightDelta[l][i][j];
                        weight[l][i][j] -= weigtdelta;

                        previousWeightDelta[l][i][j] = weigtdelta;
                    }
                }
            }

            for (int l = 0; l < layerCount; l++)
            {
                for (int i = 0; i < layerSize[l]; i++)
                {
                    biasDelta   = TrainingRate * delta[l][i] + Momentum * previosBiasDelta[l][i];
                    bias[l][i] -= biasDelta;

                    previosBiasDelta[l][i] = biasDelta;
                }
            }

            return(error);
        }
コード例 #2
0
        // Функція навчання
        public double Train(ref double[] input, ref double[] desired, double kCoefficient, double bCoefficient, double eCoefficient, double Momentum)
        {
            // Перевірка вхідних параметрів
            if (input.Length != inputSize)
            {
                throw new ArgumentException("Invalid input parameter", "input");
            }

            if (desired.Length != layerSize[layerCount - 1])
            {
                throw new ArgumentException("Invalid input parameter", "desired");
            }

            // Локальні змінні
            double error = 0.0, sum = 0.0, weigtdelta = 0.0, biasDelta = 0.0, phiDelta = 0.0, phiDeltaSecond = 0.0;

            double[] output = new double[layerSize[layerCount - 1]];

            // Запуск мережі
            Run(ref input, out output);

            //Розмножуємо похибку у зворотньму порядку
            for (int l = layerCount - 1; l >= 0; l--)
            {
                //Вихідний шар
                if (l == layerCount - 1)
                {
                    for (int k = 0; k < layerSize[l]; k++)
                    {
                        delta[l][k]  = output[k] - desired[k];
                        error       += Math.Pow(delta[l][k], 2);
                        delta[l][k] *= TransferFunctions.DerivativeEvaluate(transferFunction[l], layerInput[l][k]);
                    }
                }
                //Прихований шар
                else
                {
                    for (int i = 0; i < layerSize[l]; i++)
                    {
                        sum = 0.0;
                        for (int j = 0; j < layerSize[l + 1]; j++)
                        {
                            sum += weight[l + 1][i][j] * delta[l + 1][j];
                        }
                        sum        *= TransferFunctions.DerivativeEvaluate(transferFunction[l], layerInput[l][i]);
                        delta[l][i] = sum;
                    }
                }
            }

            // Оновлення ваг та відхилень
            for (int l = 0; l < layerCount; l++)
            {
                for (int i = 0; i < (l == 0 ? inputSize : layerSize[l - 1]); i++)
                {
                    for (int j = 0; j < layerSize[l]; j++)
                    {
                        phiDelta       = delta[l][j] * (l == 0 ? input[i] : layerOtput[l - 1][i]); // обрахунок phi для поточної ваги
                        phiDeltaSecond = (1 - eCoefficient) * previousPhiDelta[l][i][j]
                                         + eCoefficient * previousPhiDeltaSecond[l][i][j];         // обрахунок phiSecond для поточної ваги

                        // оновлення швидкості навчання для ваги
                        learningRates[l][i][j] +=
                            CalculateLearningRateDelta(previousPhiDeltaSecond[l][i][j], phiDelta, kCoefficient, bCoefficient, learningRates[l][i][j]);

                        weigtdelta       = learningRates[l][i][j] * phiDelta + Momentum * previousWeightDelta[l][i][j];
                        weight[l][i][j] -= weigtdelta;

                        previousWeightDelta[l][i][j]    = weigtdelta;
                        previousPhiDelta[l][i][j]       = phiDelta;
                        previousPhiDeltaSecond[l][i][j] = phiDeltaSecond;
                    }
                }
            }

            for (int l = 0; l < layerCount; l++)
            {
                for (int i = 0; i < layerSize[l]; i++)
                {
                    biasDelta   = initialLearningRate * delta[l][i] + Momentum * previosBiasDelta[l][i];
                    bias[l][i] -= biasDelta;

                    previosBiasDelta[l][i] = biasDelta;
                }
            }

            return(error);
        }