神经网络没有经过训练。错误在哪里? [关闭]

问题描述 投票:0回答:0

我正在研究 Tarik Rashid 的书《构建神经网络》。书上有python的例子,我想用c#实现,矩阵乘法函数也是我自己的。训练通过,但网络未训练。 我想出了一个小数据集,但是通过 Predict 函数后,没有返回任何目标值。请帮助我了解错误在哪里。

public class NeuralNetwork
    {
        private int InCount { get; }
        private int OutCount { get; }
        private int HiddenCount { get;}
        private double LearningRate { get; set; }
        private double[,] wih;
        private double[,] who;
       
      

        public NeuralNetwork(int In, int Hid, int Out)
        {
            InCount = In;
            OutCount = Out;
            HiddenCount = Hid;

            wih = new double[HiddenCount, InCount];
            who = new double[OutCount, HiddenCount];

            Random rand = new Random();
          for (int i = 0; i < wih.GetLength(0); i++)
                for (int j = 0; j < wih.GetLength(1); j++)
                wih[i, j] = rand.NextDouble() - 0.5;

          for(int i = 0; i < who.GetLength(0); i++)
                for (int j = 0; j < who.GetLength(1); j++)
                    who[i, j] = rand.NextDouble() - 0.5;

        }

         public double [,] Predict (double [,] Inputs_list)
          {
            double[,] hidden_inputs = Dot(wih, Inputs_list);
            double[,] hidden_outputs = Sigma(hidden_inputs);
            double [,] final_inputs = Dot(who, hidden_outputs);
            double[,] final_outputs = Sigma(final_inputs);

            return final_outputs;
          }

        #region Matrix Operations

        static double[,] Dot(double[,] a, double[,] b)
        {
            if (a.GetLength(1) != b.GetLength(0)) throw new Exception("The number of columns in the first matrix must be equal to the number of rows in the second matrix.");
            double[,] r = new double[a.GetLength(0), b.GetLength(1)];
            for(int i = 0; i < a.GetLength(0); i++)
            {
                for (int j = 0; j < b.GetLength(1); j++)
                {
                    for (int k = 0; k < a.GetLength(1); k++)
                    {

                        r[i, j] += a[i, k] * b[k, j];
                    }
                }
            }
      
       
            return r;

        }
        static double [,] Multiplacation(double b, double[,] a)
        {
            double [,] r = new double[a.GetLength(0), a.GetLength(1)];
            for(int i = 0; i < a.GetLength(0); i++)
                for(int j = 0; j < a.GetLength(1); j++)
                    r[i, j] = a[i, j] * b;
            return r;
        }
        static double[,] Multiplacation(double [,] a, double[] b)
        {
            double[,] r = new double[a.GetLength(0), a.GetLength(1)];
            for (int i = 0; i < a.GetLength(0); i++)
                for (int j = 0; j < a.GetLength(1); j++)
                    r[i, j] = a[i, j] * b[j];
            return r;
        }

        static double[,] Multiplacation(double[,] a, double[,] b)
        {
            double[,] r = new double[a.GetLength(0), a.GetLength(1)];
            for (int i = 0; i < a.GetLength(0); i++)
                for (int j = 0; j < b.GetLength(1); j++)  //a.GetLength
                    r [i,j] = a[i, j] * b[i, j];
            return r;
        }
        static double[,] Transpose (double [,] matrix)
        {
            int rows = matrix.GetLength(1);
            int cols = matrix.GetLength(0);
            double[,] result = new double[rows, cols];
            for(int i = 0; i < cols; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    result[j, i] = matrix[i, j];
                }
            }
            return result;
        }

        private double[,] Difference(double[,] a, double[,] b)
        {
            double[,] r = new double[a.GetLength(0), b.GetLength(1)];
            for (int i = 0; i < a.GetLength(0); i++)
                for (int j = 0; j < a.GetLength(1); j++)
                {
                    r[i, j] = a[i, j] - b[i, j];
                }
            return r;
        }
        static double[,] Difference(double[,] a, double[] b)
        {
            double[,] r = new double[a.GetLength(0), b.GetLength(0)];
            for (int i = 0; i < a.GetLength(0); i++)
                for (int j = 0; j < a.GetLength(1); j++)
                {
                    r[i, j] = a[i, j] - b[i];
                }
            return r;
        }

        double [,] Add (double[,] a, double[,] b)
        {
            double[,] r = new double [a.GetLength(0), a.GetLength(1)];
            for(int i = 0; i < a.GetLength(0); i++)
                for(int j = 0; j < a.GetLength(1); j++)
                {
                    r[i, j] = a[i, j] + b[i,j];
                }
            return r;
        }

        #endregion

        #region Sigma
        private double[,] Sigma(double[,] matrix)   //исправлено
        {
            double [,] result = new double[matrix.GetLength(0), matrix.GetLength(1)];
            for (int i = 0; i < matrix.GetLength(0); i++)
                for (int j = 0; j < matrix.GetLength(1); j++)
                { double x = matrix[i, j];
                    
                        result[i, j] = 1 / (1 + Math.Exp(-(matrix[i, j])));
                   
                }    
                 

            return result;
        }
        private double[,] SigmaGradient(double [,] matrix)
        {
            double [,] result = new double[matrix.GetLength(0), matrix.GetLength(1)];
            for (int i = 0; i < matrix.GetLength(0); i++)
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    double sigmoid = 1 / (1 + Math.Exp(-(matrix[i, j])));
                    result[i, j] = sigmoid * (1 - sigmoid);
                }
            return result;
        }

        #endregion

        public void Training (double [,] inputs_list,double [,] target_list, double lr, int epoch)
        {
            LearningRate = lr;

            for (int e = 0; e < epoch; e++)
            {
                
                double[,] hidden_inputs = Dot(wih, inputs_list);
                double[,] hidden_outputs = Sigma(hidden_inputs); //
                double[,] final_inputs = Dot(who, hidden_outputs);
                double[,] final_outputs = Sigma(final_inputs);   //

                double[,] outputs_errors = Difference(target_list, final_outputs);
                double[,] outputGrad = SigmaGradient(outputs_errors);
                double[,] outputDelta = Multiplacation(outputs_errors, outputGrad);
                who = Add(who, Transpose(Multiplacation(LearningRate, Dot(hidden_outputs, outputDelta)))); //Update weights between hidden layer and output layer

                double[,] hidden_errors = Dot(outputDelta, who);   // Update weights between input layer and hidden layer
                double[,] hiddenGrad = SigmaGradient(hidden_outputs);
                double[,] hiddenDelta = Multiplacation(hidden_errors, hiddenGrad);
                wih = Add(wih, Transpose(Multiplacation(LearningRate, Dot(inputs_list, hiddenDelta))));
}
}

static void Main(string[] args)
        {
            double[,] inputData = new double[4,2]; //[][] 4,2
            double [,] targetData = new double[2,2];    //2,2

            #region fill
            inputData[0, 0] = 0.5;
            inputData[0, 1] = 0;
            inputData[1, 0] = 1;
            inputData [1, 1] = 0.6;
            inputData[2, 0] = 0;
            inputData[2, 1] = 1;
            inputData[3, 0] = 0.4;
            inputData[3, 1] = 1;

            targetData [0, 0] = 0.9;
            targetData[0, 1] = 1;
            targetData[1, 0] = 0;
            targetData[1, 1] = 1;


            #endregion

            NeuralNetwork network = new NeuralNetwork(4, 3, 2);
            network.Training(inputData, targetData, 0.07, 2000);  //0.2 100
            network.Predict(inputData);

        }
c# neural-network matrix-multiplication
© www.soinside.com 2019 - 2024. All rights reserved.