コード例 #1
0
ファイル: NN.cs プロジェクト: qdm097/ChessAIProject
 public void Descend(double[] input, double momentum, double learningrate, bool output, bool usemomentum)
 {
     for (int i = 0; i < Length; i++)
     {
         for (int ii = 0; ii < InputLength; ii++)
         {
             //Weight gradients
             WeightGradient[i, ii] = input[ii] * ActivationFunctions.TanhDerriv(Values[i]) * Errors[i];
             if (usemomentum)
             {
                 WeightMomentum[i, ii]  = (WeightMomentum[i, ii] * momentum) - (learningrate * WeightGradient[i, ii]);
                 WeightGradient[i, ii] += WeightMomentum[i, ii];
             }
         }
         if (output)
         {
             continue;
         }
         //Bias gradients
         BiasGradient[i] = ActivationFunctions.TanhDerriv(Values[i]) * Errors[i];
         if (usemomentum)
         {
             BiasMomentum[i]  = (BiasMomentum[i] * momentum) - (learningrate * BiasGradient[i]);
             BiasGradient[i] += BiasMomentum[i];
         }
     }
 }
コード例 #2
0
ファイル: NN.cs プロジェクト: qdm097/ChessAIProject
 public void Backprop(Layer output)
 {
     Errors = new double[Length];
     for (int k = 0; k < output.Length; k++)
     {
         for (int j = 0; j < Length; j++)
         {
             Errors[j] += output.Weights[k, j] * ActivationFunctions.TanhDerriv(output.Values[k]) * output.Errors[k];
         }
     }
 }
コード例 #3
0
ファイル: NN.cs プロジェクト: qdm097/ChessAIProject
 public void Calculate(double[] input, bool output)
 {
     Values = new double[Length];
     for (int k = 0; k < Length; k++)
     {
         for (int j = 0; j < InputLength; j++)
         {
             Values[k] += ((Weights[k, j] + WeightMomentum[k, j]) * input[j]);
         }
         if (!output)
         {
             Values[k] += Biases[k] + BiasMomentum[k];
             Values[k]  = ActivationFunctions.Tanh(Values[k]);
         }
         else
         {
             Values[k] = Values[k];
         }
     }
 }
コード例 #4
0
ファイル: Form1.cs プロジェクト: qdm097/ChessAIProject
        private void Button2_Click(object sender, EventArgs e)
        {
            //This button is a toggle (prevents clicking before ready again, as well)
            if (Training)
            {
                Training = false; Buttons[1].Enabled = false; return;
            }
            Training = true;
            //Need to check number of games
            //Index 0 is file format
            var thread =
                new Thread(() =>
            {
                //TODO: find actual number of games available

                for (int j = 1; j < 20058; j++)
                {
                    while (Training)
                    {
                        var moves = IO.ReadGame(j);
                        for (int c = 0; c < moves.Count; c++)
                        {
                            //Whatever the player did is the right move
                            var possibilities = new List <Board>();
                            //Generate moves from the same board as the players
                            if (c != 0)
                            {
                                possibilities = moves[c - 1].GenMoves(true);
                            }
                            //Generate moves from a fresh board if none exists prior in array
                            else
                            {
                                possibilities = (new Board(new Player(true), new Player(false), new Piece[8, 8], true).initBoard().GenMoves(true));
                            }
                            //Translate board to numbers
                            var doubleboard = eval(moves[c], c % 2 == 0);
                            //Foreach move the player could have made, evaluate it in relation to their actual move
                            foreach (Board b in possibilities)
                            {
                                //The player's move was the right one
                                if (b.RecentMove[0] == moves[c].RecentMove[0] && b.RecentMove[1] == moves[c].RecentMove[1])
                                //Calculation and backpropegation of error
                                {
                                    ActiveNN.Run(ActivationFunctions.Normalize(doubleboard, 8, 8), 1, false);
                                }
                                //Other moves are not
                                else
                                {
                                    ActiveNN.Run(ActivationFunctions.Normalize(doubleboard, 8, 8), 0, false);
                                }
                            }

                            //TODO: add feedback for evaluating player board states (one of the players won after all)
                        }
                        //Batch descent
                        ActiveNN.Run(moves.Count);
                        //Enable button in case it was disabled before continuing (once save is finished)
                        if (j % SaveEveryX == 0)
                        {
                            new Task(() => { IO.Write(ActiveNN, 0); Invoke(new Action(() => { Buttons[1].Enabled = true; })); }).Start();
                        }
                    }
                }
            });

            thread.IsBackground = true;
            thread.Start();

            double[,] eval(Board move, bool isw)
            {
                var input = new double[8, 8];

                for (int i = 0; i < 8; i++)
                {
                    for (int ii = 0; ii < 8; ii++)
                    {
                        //Set piece values equal to standard chess piece values
                        Piece p = move.Pieces[i, ii];
                        //Don't have to set empty piece = 0 b/c array initialization does it automatically
                        if (p is Empty)
                        {
                            continue;
                        }
                        if (p is Pawn)
                        {
                            input[i, ii] = 1d;
                        }
                        if (p is Knight || p is Bishop)
                        {
                            input[i, ii] = 3d;
                        }
                        if (p is Rook)
                        {
                            input[i, ii] = 5d;
                        }
                        if (p is Queen)
                        {
                            input[i, ii] = 9d;
                        }
                        if (p is King)
                        {
                            input[i, ii] = 15d;
                        }

                        //Set opposite color piece values to negative
                        if (p.Player.IsW != isw)
                        {
                            input[i, ii] *= -1;
                        }
                    }
                }
                return(input);
            }
        }