/// <summary>
        /// Load a vector from a file
        /// </summary>
        public static SimpleNeuralNetwork Load(BinaryReader r)
        {
            SimpleNeuralNetwork snn = new SimpleNeuralNetwork();

            snn.inputsCount = r.ReadInt32();
            snn.hiddenCount = r.ReadInt32();
            snn.outputCount = r.ReadInt32();

            snn.weights_IH = new double[snn.inputsCount, snn.hiddenCount];
            snn.weights_HO = new double[snn.hiddenCount, snn.outputCount];

            for (int i = 0; i < snn.inputsCount; i++)
            {
                for (int h = 0; h < snn.hiddenCount; h++)
                {
                    snn.weights_IH[i, h] = r.ReadDouble();
                }
            }

            for (int h = 0; h < snn.hiddenCount; h++)
            {
                for (int o = 0; o < snn.outputCount; o++)
                {
                    snn.weights_HO[h, o] = r.ReadDouble();
                }
            }

            snn.neurons_H = new double[r.ReadInt32()];
            for (int h = 0; h < snn.hiddenCount; h++)
            {
                snn.neurons_H[h] = r.ReadDouble();
            }

            snn.neurons_O = DoubleVector.Load(r);

            snn.error_H = new double[r.ReadInt32()];
            for (int h = 0; h < snn.error_H.Length; h++)
            {
                snn.error_H[h] = r.ReadDouble();
            }

            snn.error_O = new double[r.ReadInt32()];
            for (int h = 0; h < snn.error_O.Length; h++)
            {
                snn.error_O[h] = r.ReadDouble();
            }

            snn.learningRate = r.ReadDouble();

            return(snn);
        }
        public SimpleNeuralNetSolver(string characterSet, int imageWidth, int imageHeight, int hiddenNeurons, int charactersPerImage, double learningRate)
        {
            // Split the set of characters into a list
            charsSet = characterSet.ToCharStringList();
            charsPerImage = charactersPerImage;
            learnRate = learningRate;

            ExpectedWidth = imageWidth;
            ExpectedHeight = imageHeight;

            sann = new SimpleNeuralNetwork(imageWidth * imageHeight, hiddenNeurons, characterSet.Length, learningRate);
            sann.OnTrainingProgressChange += new SimpleNeuralNetwork.TrainingProgressHandler(sann_OnTrainingProgressChange);

            trainerWorker = new BackgroundWorker();
            trainerWorker.DoWork += new DoWorkEventHandler(worker_DoWork);
            trainerWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            trainerWorker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            trainerWorker.WorkerReportsProgress = true;

            testerWorker = new BackgroundWorker();
            testerWorker.DoWork += new DoWorkEventHandler(testerWorker_DoWork);
            testerWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(testerWorker_RunWorkerCompleted);
        }
        /// <summary>
        /// Load a vector from a file
        /// </summary>
        public static SimpleNeuralNetwork Load(BinaryReader r)
        {
            SimpleNeuralNetwork snn = new SimpleNeuralNetwork();

            snn.inputsCount = r.ReadInt32();
            snn.hiddenCount = r.ReadInt32();
            snn.outputCount = r.ReadInt32();

            snn.weights_IH = new double[snn.inputsCount, snn.hiddenCount];
            snn.weights_HO = new double[snn.hiddenCount, snn.outputCount];

            for (int i = 0; i < snn.inputsCount; i++)
            {
                for (int h = 0; h < snn.hiddenCount; h++)
                {
                    snn.weights_IH[i, h] = r.ReadDouble();
                }
            }

            for (int h = 0; h < snn.hiddenCount; h++)
            {
                for (int o = 0; o < snn.outputCount; o++)
                {
                    snn.weights_HO[h, o] = r.ReadDouble();
                }
            }

            snn.neurons_H = new double[r.ReadInt32()];
            for (int h = 0; h < snn.hiddenCount; h++)
            {
                snn.neurons_H[h] = r.ReadDouble();
            }

            snn.neurons_O = DoubleVector.Load(r);

            snn.error_H = new double[r.ReadInt32()];
            for (int h = 0; h < snn.error_H.Length; h++)
            {
                snn.error_H[h] = r.ReadDouble();
            }

            snn.error_O = new double[r.ReadInt32()];
            for (int h = 0; h < snn.error_O.Length; h++)
            {
                snn.error_O[h] = r.ReadDouble();
            }

            snn.learningRate = r.ReadDouble();

            return snn;
        }
 public override void Load(BinaryReader r)
 {
     base.Load(r);
     charsPerImage = r.ReadInt32();
     charsSet = r.ReadString().ToCharArray().ToList().Select(c => c.ToString()).ToList();
     learnRate = r.ReadDouble();
     sann = SimpleNeuralNetwork.Load(r);
     sann.OnTrainingProgressChange += new SimpleNeuralNetwork.TrainingProgressHandler(sann_OnTrainingProgressChange);
 }