/// <summary>
 /// Create a new digit neural network
 /// </summary>
 /// <param name="sender">sender object</param>
 /// <param name="e">event</param>
 private void newDigitToolStripMenuItem_Click(object sender, EventArgs e)
 {
     int[] layers = new int[3] {
         784, 100, 10
     };
     DigitNN.init(out digitNN, layers);
     pictureBoxAI.Image = Properties.Resources.ai;
     digit = true;
 }
 /// <summary>
 /// Determine the drawn image and determine the output
 /// </summary>
 /// <param name="sender">sender object</param>
 /// <param name="e">event</param>
 private void aiDetermineButton_Click(object sender, EventArgs e)
 {
     if (digitNN != null)
     {
         double[] input  = DigitNN.transformBitmapdata(B);
         byte     result = digitNN.determine(input);
         if (aiTextBox.Lines.Length == 6)
         {
             NeuralNetwork.CustomTextBox temp = new NeuralNetwork.CustomTextBox();
             for (int i = 1; i < aiTextBox.Lines.Length; i++)
             {
                 temp.Text += aiTextBox.Lines[i] + "\n";
             }
             temp.Text     += "I think it is a " + result + " :)";
             aiTextBox.Text = temp.Text;
         }
         else
         {
             aiTextBox.Text += "\nI think it is a " + result + " :)";
         }
     }
     if (letterNN != null)
     {
         double[] input  = LetterNN.transformBitmapdata(B);
         char     result = letterNN.determine(input);
         if (aiTextBox.Lines.Length == 6)
         {
             NeuralNetwork.CustomTextBox temp = new NeuralNetwork.CustomTextBox();
             for (int i = 1; i < aiTextBox.Lines.Length; i++)
             {
                 temp.Text += aiTextBox.Lines[i] + "\n";
             }
             if (result != 0)
             {
                 temp.Text += "I think it is a " + result + " :)";
             }
             else
             {
                 temp.Text += "I'm not sure :(";
             }
             aiTextBox.Text = temp.Text;
         }
         else
         {
             if (result != 0)
             {
                 aiTextBox.Text += "\nI think it is a " + result + " :)";
             }
             else
             {
                 aiTextBox.Text += "\nI'm not sure :(";
             }
         }
     }
 }
        /// <summary>
        /// Load digit ai
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            double[][][] loadedWeights;
            double[][]   loadedBiases;
            int[]        header;
            int          layerLength = 0;
            int          wbOffset    = 0;

            string       file   = "NULL";
            DialogResult result = openFileDialog.ShowDialog();

            if (result == DialogResult.OK) // Test result.
            {
                file = openFileDialog.FileName;

                byte[] fileByte = File.ReadAllBytes(file);

                layerLength = fileByte[0];
                header      = new int[layerLength];
                wbOffset   += INT_SIZE;

                for (int i = 0; i < layerLength; i++)
                {
                    header[i] = BitConverter.ToInt32(fileByte, INT_SIZE * i + INT_SIZE);
                    wbOffset += INT_SIZE;
                }
                //header length: 4, 784     100     100    10
                loadedWeights = new double[layerLength - 1][][];
                for (int i = 0; i < layerLength - 1; i++)
                {
                    loadedWeights[i] = new double[header[i + 1]][];
                    for (int j = 0; j < header[i + 1]; j++)
                    {
                        loadedWeights[i][j] = new double[header[i]];
                        Buffer.BlockCopy(fileByte, wbOffset, loadedWeights[i][j], 0, loadedWeights[i][j].Length * DOUBLE_SIZE);
                        wbOffset += loadedWeights[i][j].Length * DOUBLE_SIZE;
                    }
                }

                loadedBiases = new double[layerLength - 1][];
                for (int i = 0; i < layerLength - 1; i++)
                {
                    loadedBiases[i] = new double[header[i + 1]];
                    Buffer.BlockCopy(fileByte, wbOffset, loadedBiases[i], 0, loadedBiases[i].Length * DOUBLE_SIZE);
                    wbOffset += loadedBiases[i].Length * DOUBLE_SIZE;
                }
                digitNN = new NeuralNetwork <byte>(header);
                DigitNN.init(out digitNN, header);
                digitNN.testWB(ref loadedWeights, ref loadedBiases);
                pictureBoxAI.Image = Properties.Resources.ai;
                digit = true;
            }
        }
        /// <summary>
        /// Thread for digit training
        /// </summary>
        private void trainDigitThread()
        {
            double[][] transformedData = DigitNN.transformBitmapdata(data);
            int        epochs          = 30;
            int        batchSize       = 10;

            double[][] trainData      = null;
            double[][] validset       = null;
            byte[]     trainLabels    = null;
            byte[]     validsetLabels = null;
            if (labelsDigit.Length == 10000)
            {
                DigitNN.splitIntoTrainAndValidset(transformedData, out trainData, out validset, labelsDigit.Length - labelsDigit.Length / 10);
                DigitNN.splitIntoTrainAndValidsetLabels(labelsDigit, out trainLabels, out validsetLabels, labelsDigit.Length - labelsDigit.Length / 10);
            }
            if (labelsDigit.Length == 60000)
            {
                DigitNN.splitIntoTrainAndValidset(transformedData, out trainData, out validset, labelsDigit.Length - labelsDigit.Length / 6);
                DigitNN.splitIntoTrainAndValidsetLabels(labelsDigit, out trainLabels, out validsetLabels, labelsDigit.Length - labelsDigit.Length / 6);
            }
            Train <byte> .trainNetwork(digitNN, trainData, validset, labelsDigit, validsetLabels, epochs, batchSize, aiTextBox);

            pictureBoxAI.Image = Properties.Resources.ai;
        }