示例#1
0
        static void Main(string[] args)
        {
            String name;
            Bitmap img;
            int    resizedWidth  = 1000;
            int    resizedHeight = 1000;

            double[] expected = { 0, 0, 0, 0, 0, 0, 1 };

            do
            {
                Console.WriteLine("Enter an image:");                                    //get image filepath
                name = Console.ReadLine();
            } while (!ImageUtil.VerifyImage(name));                                      //make sure image is actually image and not large

            img = Bitmap.FromFile(name) as Bitmap;                                       //do this again here so we have it but know it's legit
            Bitmap resizedImg = ImageUtil.ResizeImage(img, resizedWidth, resizedHeight); //resize the image so it doesn't take multiple millenia

            resizedImg.Save("resized.png", System.Drawing.Imaging.ImageFormat.Png);
            int[] rgb = new int[resizedWidth * resizedHeight]; //holds int rgb values
            ImageUtil.getRGB(resizedImg, 0, 0, resizedWidth, resizedHeight, rgb, 0, resizedWidth);

            double[] input = new double[resizedWidth * resizedHeight]; //since we need doubles for compression to not have floating point errors
            for (int i = 0; i < rgb.Length; i++)
            {
                input[i] = Compressions.rgbcomp(rgb[i]); //compress int rgb values and put them into input
            }

            Layer initial = new Layer(input); //create initial layer with compressed activation values

            Console.WriteLine("How many hidden layers?");
            int numhidden = Convert.ToInt16(Console.ReadLine());

            int[] hidden = new int[numhidden];
            for (int i = 0; i < numhidden; i++)
            {
                Console.WriteLine("How many neurons in hidden layer " + i + "?");
                hidden[i] = Convert.ToInt16(Console.ReadLine());
            }

            Network neural = new Network(resizedWidth * resizedHeight, hidden, 7);

            neural.randomizeAll();

            for (int i = 0; i < 100; i++)
            {
                int errorCode = runNetwork(neural, input, expected);
                if (errorCode == -1)
                {
                    Console.WriteLine("Intended output is a dead neuron, killing network.");
                    Console.ReadKey();
                    return;
                }
                else if (errorCode == -2)
                {
                    Console.WriteLine("Every output is a dead neuron, killing network.");
                    Console.ReadKey();
                    return;
                }
            }

            Console.ReadKey();
        }
示例#2
0
        public GradStep[] backpropogate(double[] expected)
        {
            double[][] errorPerActivation = new double[hiddenLayers.Count() + 1][]; //change in error per change in activation, multiplied by change in activation per change in weight/bias to give gradient
            GradStep[] steps = new GradStep[hiddenLayers.Count() + 1];              //the changes in weights and biases for each hidden layer, plus the output

            //Calculate changes for final layer
            errorPerActivation[hiddenLayers.Count()] = new double[output.weights.RowCount];                                     //have to initialize each array because it's jagged and c# is the dicks
            steps[steps.Count() - 1] = new GradStep(output.weights.RowCount, output.weights.ColumnCount, output.neurons.Count); //initialize gradstep for the output
            for (int i = 0; i < output.weights.RowCount; i++)
            {
                errorPerActivation[hiddenLayers.Count()][i] = 2 * (expected[i] - output.neurons[i]) * Compressions.derReLU(output.neurons[i]); //change in error per change in activation for the final layer
                for (int j = 0; j < output.weights.ColumnCount; j++)
                {
                    steps[steps.Count() - 1].weightStep[i, j] = errorPerActivation[hiddenLayers.Count()][i] * hiddenLayers[hiddenLayers.Count() - 1].neurons[j]; //the change in weight is the error/activation times activation/weight
                }
                steps[steps.Count() - 1].biasStep[i] = errorPerActivation[hiddenLayers.Count()][i];                                                              //change in error with respect to bias is just error/activation, since activation/bias is 1 (bias is constant)
            }

            for (int i = hiddenLayers.Count() - 1; i >= 0; i--) //for every hidden layer, iterating backwards since we need the next layer's error
            {
                DerivedLayer nextLayer;
                Layer        previousLayer;
                errorPerActivation[i] = new double[hiddenLayers[i].weights.RowCount];                                                         //have to initialize each array because it's jagged and c# is the balls
                steps[i] = new GradStep(hiddenLayers[i].weights.RowCount, hiddenLayers[i].weights.ColumnCount, hiddenLayers[i].biases.Count); //holds suggested changes to weights and biases in this layer

                if (i < hiddenLayers.Count() - 1)
                {
                    nextLayer = hiddenLayers[i + 1]; //use values from next hidden layer
                }
                else
                {
                    nextLayer = output; //unless it's the final hidden layer, in which case we need values of output
                }

                if (i > 0)
                {
                    previousLayer = hiddenLayers[i - 1]; //use values from previous hidden layer
                }
                else
                {
                    previousLayer = input; //unless it's the final hidden layer, in which case we need values of input
                }

                for (int j = 0; j < hiddenLayers[i].weights.RowCount; j++)                                  //in every row
                {
                    double activation = Compressions.derReLU(hiddenLayers[i].neurons[j]);                   //find the change in error per change in activation
                    errorPerActivation[i][j] = 0;
                    for (int k = 0; k < nextLayer.neurons.Count(); k++)                                     //since this activation affects every neuron in next layer, we need changes for all of them
                    {
                        errorPerActivation[i][j] += nextLayer.weights[k, j] * errorPerActivation[i + 1][k]; //change in activation per weight times change in error per activation
                        steps[i].biasStep[j]     += errorPerActivation[i + 1][k];                           //change in error with respect to bias is just error/activation, since activation/bias is 1 (bias is constant)
                    }

                    errorPerActivation[i][j] *= activation;                       //multiply error in activation by derivative of compression to complete the gradient

                    for (int k = 0; k < hiddenLayers[i].weights.ColumnCount; k++) //adjust every weight
                    {
                        steps[i].weightStep[j, k] = errorPerActivation[i][j] * previousLayer.neurons[k];
                    }
                }
            }

            return(steps);
        }