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]); } }
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); }
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); } }
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)) + "%"); }