예제 #1
0
        public static void Run()
        {
            var trainingSets = LoadTrainingSets();

            Network network = new Network(13, 1, 4, 3);
            network.AddBiasNeuron(0);
            double error = 0;
            double deltaDrop = 0;
            int tries = 0;
            do
            {
                //if (tries % 5 == 0 && deltaDrop < 0.5)
                //{
                //    Console.Write("Randomizing weights");
                //    network.RandomizeWeights();
                //}
                Console.WriteLine("Optimizing...");
                //network.Weights = BruteOptimizer.OptimizeMulti(network, trainingSets);
                network.Weights = BackPropOptimizer.Optimize(network, trainingSets, 2, 1);
                var newError = network.Error(trainingSets, network.Weights);
                deltaDrop = error - newError;
                error = newError;
                Console.WriteLine("Error from last optimization attempt: " + error);
                tries++;
            } while (error > 5 /*false || error > 10 || deltaDrop < 1*/);

            Console.WriteLine("Optimization complete!");
            while (true)
            {
                Console.Write("Enter comma-separated inputs: ");
                var inputs = Console.ReadLine().Split(',');
                if (inputs.Length == 1)
                {
                    break;
                }
                var inputArray = new double[13];
                for (var i = 0; i < 13; i++)
                {
                    var minVal = RawTrainingSets.Min(set => set.Inputs[i]);
                    var maxVal = RawTrainingSets.Max(set => set.Inputs[i]);
                    inputArray[i] = Normalize(double.Parse(inputs[i].Trim()), minVal, maxVal);
                }
                var output = network.Pulse(inputArray);
                Console.WriteLine(output[0] + " " + output[1] + " " + output[2]);
            }
        }
예제 #2
0
        public static void Reconstruct(string path, bool demoMode)
        {
            var folderPath = path.Replace(".nimg", ".nimg-temp");

            if (Directory.Exists(folderPath))
            {
                Directory.Delete(folderPath, true);
            }
            Directory.CreateDirectory(folderPath);
            ZipFile.ExtractToDirectory(path, folderPath);
            folderPath += "\\";

            //Read the colors
            var colors = new List <Color>();

            using (var reader = new BinaryReader(new FileStream(folderPath + "colors.list", FileMode.Open)))
            {
                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    var R = Convert.ToInt32(reader.ReadByte());
                    var G = Convert.ToInt32(reader.ReadByte());
                    var B = Convert.ToInt32(reader.ReadByte());
                    colors.Add(Color.FromArgb(R, G, B));
                }
            }

            //Load the network
            Network network;
            var     inputPixels = 0;

            using (var reader = new BinaryReader(new FileStream(folderPath + "weights.nn", FileMode.Open)))
            {
                inputPixels = Convert.ToInt32(reader.ReadByte());
                var innerLayers     = Convert.ToInt32(reader.ReadByte());
                var neuronsPerLayer = Convert.ToInt32(reader.ReadByte());
                var biasNeurons     = Convert.ToInt32(reader.ReadByte());
                network = new Network(inputPixels * 3, innerLayers, neuronsPerLayer, 3);
                network.RandomizeWeights();
                for (var i = 0; i < biasNeurons; i++)
                {
                    network.AddBiasNeuron(i);
                }

                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    for (var i = 0; i < network.Weights.Length; i++)
                    {
                        for (var j = 0; j < network.Weights[i].Length; j++)
                        {
                            for (var k = 0; k < network.Weights[i][j].Length; k++)
                            {
                                network.Weights[i][j][k] = reader.ReadDouble();
                            }
                        }
                    }
                }
            }

            //Construct the image
            using (var reader = new BinaryReader(new FileStream(folderPath + "image.data", FileMode.Open)))
            {
                var width           = reader.ReadInt32();
                var height          = reader.ReadInt32();
                var colorIndexBytes = Convert.ToInt32(reader.ReadByte());

                using (var reconstructedImage = new Bitmap(width, height))
                {
                    for (var yPixel = 0; yPixel < height; yPixel++)
                    {
                        var input = new double[inputPixels * 3];
                        for (var xPixel = 0; xPixel < width; xPixel++)
                        {
                            var byteStr = Convert.ToString(reader.ReadByte(), 2).PadLeft(8, '0');
                            if (byteStr.StartsWith("1111"))
                            {
                                var inARow = Convert.ToInt32(byteStr.Substring(4).PadLeft(8, '0'), 2) + 1; // 11110000 -> 1, not 0
                                for (var i = 0; i < inARow; i++)
                                {
                                    if (demoMode)
                                    {
                                        reconstructedImage.SetPixel(xPixel, yPixel,
                                                                    Color.FromArgb(255, 0, 0));
                                        xPixel++;
                                        continue;
                                    }

                                    var output        = network.Pulse(input);
                                    var roundedOutput = new int[] {
                                        (int)Math.Round(output[0] * 255),
                                        (int)Math.Round(output[1] * 255),
                                        (int)Math.Round(output[2] * 255)
                                    };

                                    reconstructedImage.SetPixel(xPixel, yPixel,
                                                                Color.FromArgb(roundedOutput[0], roundedOutput[1], roundedOutput[2]));

                                    for (var j = 0; j < input.Length - 3; j++)
                                    {
                                        input[j] = input[j + 3];
                                    }
                                    input[input.Length - 3] = output[0];
                                    input[input.Length - 2] = output[1];
                                    input[input.Length - 1] = output[2];

                                    xPixel++;
                                }
                                xPixel--;
                            }
                            else
                            {
                                Color colorToUse;
                                if (colorIndexBytes == 0)
                                {
                                    colorToUse = Color.FromArgb(
                                        Convert.ToInt32(byteStr, 2),
                                        Convert.ToInt32(reader.ReadByte()),
                                        Convert.ToInt32(reader.ReadByte())
                                        );
                                }
                                else
                                {
                                    var colorIndex = Convert.ToInt32(byteStr, 2);
                                    if (colorIndexBytes == 2)
                                    {
                                        var secondByteStr = Convert.ToString(reader.ReadByte(), 2).PadLeft(8, '0');
                                        colorIndex = Convert.ToInt32(byteStr + secondByteStr, 2);
                                    }
                                    colorToUse = colors[colorIndex];
                                }

                                reconstructedImage.SetPixel(xPixel, yPixel, colorToUse);
                                for (var j = 0; j < input.Length - 3; j++)
                                {
                                    input[j] = input[j + 3];
                                }
                                input[input.Length - 3] = (double)colorToUse.R / 255;
                                input[input.Length - 2] = (double)colorToUse.G / 255;
                                input[input.Length - 1] = (double)colorToUse.B / 255;
                            }
                        }
                    }
                    reconstructedImage.Save(path.Replace(".nimg", ".reconstructed.png"), System.Drawing.Imaging.ImageFormat.Png);
                }
            }
            Directory.Delete(folderPath, true);
        }
예제 #3
0
        public static void Run()
        {
            TrainingSets = new TrainingSet[0];

            Network = new Network(9, 3, 10, 9);
            Network.AddBiasNeuron(0);
            Network.AddBiasNeuron(1);
            Network.AddBiasNeuron(2);
            double error = 0;

            Console.WriteLine("Optimization complete!");
            var beforePrompt = 10;
            while (true)
            {
                beforePrompt--;
                Console.WriteLine(beforePrompt);
                var control = false;
                if (beforePrompt <= 0)
                {
                    Console.WriteLine("Take control? (Type TC)");
                    control = Console.ReadLine() == "TC";
                    if (control)
                    {
                        beforePrompt = 0;
                    }
                    else
                    {
                        beforePrompt = 30;
                    }
                }
                var board = GenerateBoard(0);
                var lastMove = -1;
                var lastComputerMove = -1;

                do
                {
                    Console.WriteLine("Board: ");
                    OutputBoard(board);

                    var spot = RandomMove(board);
                    if (control)
                    {
                        Console.Write("Pick to drop an X: ");
                        spot = int.Parse(Console.ReadLine());
                    }
                    board[spot] = -1;
                    lastMove = spot;
                    if (WinnerOfBoard(board) != -2)
                    {
                        break;
                    }
                    //var computerChoice = BestNextMove(board);
                    var output = Network.Pulse(board);
                    var computerChoice = -1;
                    double computerMax = -1;
                    for (var i = 0; i < output.Length; i++)
                    {
                        if (board[i] != 0)
                        {
                            continue;
                        }
                        if (output[i] > computerMax)
                        {
                            computerChoice = i;
                            computerMax = output[i];
                        }
                    }
                    if (computerChoice == -1) computerChoice = 0;
                    board[computerChoice] = 1;
                    lastComputerMove = computerChoice;
                } while (WinnerOfBoard(board) == -2);

                var winner = WinnerOfBoard(board);
                switch (winner)
                {
                    case 0:
                        Console.WriteLine("Tie!");
                        break;
                    case -1:
                        board[lastMove] = 0;
                        var output = new double[9];
                        output[lastMove] = 1;
                        Console.WriteLine("You win!");
                        Train(new TrainingSet(board, output), 1);
                        break;
                    case 1:
                        board[lastComputerMove] = 0;
                        output = new double[9];
                        output[lastComputerMove] = 1;
                        Console.WriteLine("Computer wins!");
                        Train(new TrainingSet(board, output), -1);
                        break;
                }
                Console.WriteLine("Final Board: ");
                OutputBoard(board);
            }
        }
예제 #4
0
        public static void Compress(string file = @"Data\TrainingImages\train.png")
        {
            Directory.CreateDirectory("Output");
            var files = new string[] { file };

            var options = Loader.LoadOptions();

            var trainingSets = Loader.LoadTrainingSets(files, options);

            Network network     = new Network(options.InputPixels * 3, options.InnerLayers, options.NeuronsPerLayer, 3);
            var     biasNeurons = 1;

            network.AddBiasNeuron(0);

            Optimizer.Optimize(network, options.InputPixels, trainingSets, options.TrainingRounds);

            Writer.WriteWeights(network, options.InputPixels, options.InnerLayers, options.NeuronsPerLayer, biasNeurons);

            using (var originalImage = new Bitmap(file))
            {
                using (var imageWriter = new BinaryWriter(new FileStream(@"Output\image.data", FileMode.Create)))
                {
                    imageWriter.WriteImageMetadata(originalImage.Width, originalImage.Height, options.ColorIndexBytes);

                    using (var colorsWriter = new BinaryWriter(new FileStream(@"Output\colors.list", FileMode.Create)))
                    {
                        var colors = new List <int[]>();

                        var hits   = 0;
                        var misses = 0;

                        for (var yPixel = 0; yPixel < originalImage.Height; yPixel++)
                        {
                            var input  = new double[options.InputPixels * 3];
                            var inARow = 0;
                            for (var xPixel = 0; xPixel < originalImage.Width; xPixel++)
                            {
                                var output = network.Pulse(input);
                                output[0] = output[0] * 255;
                                output[1] = output[1] * 255;
                                output[2] = output[2] * 255;
                                var actualPixel = originalImage.GetPixel(xPixel, yPixel);
                                var toUse       = new double[3];

                                var actualColors = new int[] { actualPixel.R, actualPixel.G, actualPixel.B };

                                var good = true;
                                for (var i = 0; i < 3; i++)
                                {
                                    if (Math.Abs(actualColors[i] - output[i]) < options.WriteTolerance)
                                    {
                                        hits++;
                                        toUse[i] = output[i];
                                    }
                                    else
                                    {
                                        good = false;
                                        misses++;
                                        toUse[i] = actualColors[i];
                                    }
                                }
                                var roundedToUse = new int[] { (int)Math.Round(toUse[0]), (int)Math.Round(toUse[1]), (int)Math.Round(toUse[2]) };

                                if (good && inARow < 15 && xPixel < originalImage.Width - 1)
                                {
                                    inARow++;
                                }
                                else if (good && (inARow == 15 || xPixel == originalImage.Width - 1))
                                {
                                    inARow++;
                                    imageWriter.WriteAIByte(inARow);
                                    inARow = 0;
                                }
                                else
                                {
                                    if (inARow > 0)
                                    {
                                        imageWriter.WriteAIByte(inARow);
                                        inARow = 0;
                                    }

                                    imageWriter.WriteColor(options.ColorIndexBytes, colors, roundedToUse, colorsWriter, options.ColorIndexTolerance);
                                }

                                for (var i = 0; i < input.Length - 3; i++)
                                {
                                    input[i] = input[i + 3];
                                }
                                input[input.Length - 3] = toUse[0] / 255;
                                input[input.Length - 2] = toUse[1] / 255;
                                input[input.Length - 1] = toUse[2] / 255;
                            }
                        }
                        Console.WriteLine("Hits: " + hits + " Misses: " + misses);
                        Console.WriteLine((double)(((double)hits / (double)(hits + misses)) * 100) + "%");
                    }
                }
            }

            var ext    = file.Split('.').Last();
            var saveAs = file.Replace("." + ext, ".nimg");

            if (File.Exists(saveAs))
            {
                File.Delete(saveAs);
            }

            ZipFile.CreateFromDirectory("Output", saveAs, CompressionLevel.Optimal, false);
            Directory.Delete("Output", true);

            var originalSize = new FileInfo(file).Length;
            var newSize      = new FileInfo(saveAs).Length;

            Console.WriteLine("Original Size: " + originalSize + " New Size: " + newSize);
            Console.WriteLine("Reduction: " + ((double)100 - ((newSize * (double)100) / originalSize)) + "%");
        }