Home made
Posted: Tue Jun 16, 2026 7:46 pm
Code: Select all
program PurePascalAI; {$MODE OBJFPC} {$H+} uses SysUtils, Math; type TVector = array of Double; TMatrix = array of TVector; { TNeuralNetwork represents a 3-layer network: Input -> Hidden -> Output } TNeuralNetwork = class private FInputSize: Integer; FHiddenSize: Integer; FOutputSize: Integer; FLearningRate: Double; // Weights and Biases FWeightsIH: TMatrix; // Input to Hidden FWeightsHO: TMatrix; // Hidden to Output FBiasesH: TVector; // Hidden Biases FBiasesO: TVector; // Output Biases // Layer States (cached for backpropagation) FHiddenActivation: TVector; FOutputActivation: TVector; function Sigmoid(X: Double): Double; function SigmoidDerivative(X: Double): Double; procedure InitializeWeights; public constructor Create(InSize, HideSize, OutSize: Integer; LR: Double); procedure ForwardPropagate(const Inputs: TVector); procedure BackPropagate(const Inputs, Targets: TVector); function Predict(const Inputs: TVector): TVector; end; { TNeuralNetwork Implementation } constructor TNeuralNetwork.Create(InSize, HideSize, OutSize: Integer; LR: Double); begin FInputSize := InSize; FHiddenSize := HideSize; FOutputSize := OutSize; FLearningRate := LR; // Allocate memory for network structures SetLength(FWeightsIH, FInputSize, FHiddenSize); SetLength(FWeightsHO, FHiddenSize, FOutputSize); SetLength(FBiasesH, FHiddenSize); SetLength(FBiasesO, FOutputSize); SetLength(FHiddenActivation, FHiddenSize); SetLength(FOutputActivation, FOutputSize); Randomize; InitializeWeights; end; function TNeuralNetwork.Sigmoid(X: Double): Double; begin Result := 1.0 / (1.0 + Exp(-X)); end; function TNeuralNetwork.SigmoidDerivative(X: Double): Double; begin // X is expected to already be passed through the Sigmoid function Result := X * (1.0 - X); end; procedure TNeuralNetwork.InitializeWeights; var i, j: Integer; begin // Randomize weights between -1.0 and 1.0 for i := 0 to FInputSize - 1 do for j := 0 to FHiddenSize - 1 do FWeightsIH[i][j] := Random * 2.0 - 1.0; for i := 0 to FHiddenSize - 1 do for j := 0 to FOutputSize - 1 do FWeightsHO[i][j] := Random * 2.0 - 1.0; for j := 0 to FHiddenSize - 1 do FBiasesH[j] := Random * 2.0 - 1.0; for j := 0 to FOutputSize - 1 do FBiasesO[j] := Random * 2.0 - 1.0; end; procedure TNeuralNetwork.ForwardPropagate(const Inputs: TVector); var i, j: Integer; Sum: Double; begin // Calculate Hidden Layer Activations for j := 0 to FHiddenSize - 1 do begin Sum := FBiasesH[j]; for i := 0 to FInputSize - 1 do Sum := Sum + Inputs[i] * FWeightsIH[i][j]; FHiddenActivation[j] := Sigmoid(Sum); end; // Calculate Output Layer Activations for j := 0 to FOutputSize - 1 do begin Sum := FBiasesO[j]; for i := 0 to FHiddenSize - 1 do Sum := Sum + FHiddenActivation[i] * FWeightsHO[i][j]; FOutputActivation[j] := Sigmoid(Sum); end; end; procedure TNeuralNetwork.BackPropagate(const Inputs, Targets: TVector); var i, j: Integer; OutputErrors: TVector; HiddenErrors: TVector; OutputGradients: TVector; HiddenGradients: TVector; Sum: Double; begin SetLength(OutputErrors, FOutputSize); SetLength(HiddenErrors, FHiddenSize); SetLength(OutputGradients, FOutputSize); SetLength(HiddenGradients, FHiddenSize); // 1. Compute Output Layer Errors and Gradients for i := 0 to FOutputSize - 1 do begin OutputErrors[i] := Targets[i] - FOutputActivation[i]; OutputGradients[i] := OutputErrors[i] * SigmoidDerivative(FOutputActivation[i]) * FLearningRate; end; // 2. Compute Hidden Layer Errors and Gradients for i := 0 to FHiddenSize - 1 do begin Sum := 0.0; for j := 0 to FOutputSize - 1 do Sum := Sum + OutputErrors[j] * FWeightsHO[i][j]; HiddenErrors[i] := Sum; HiddenGradients[i] := HiddenErrors[i] * SigmoidDerivative(FHiddenActivation[i]) * FLearningRate; end; // 3. Update Hidden-to-Output Weights and Biases for j := 0 to FOutputSize - 1 do begin for i := 0 to FHiddenSize - 1 do FWeightsHO[i][j] := FWeightsHO[i][j] + FHiddenActivation[i] * OutputGradients[j]; FBiasesO[j] := FBiasesO[j] + OutputGradients[j]; end; // 4. Update Input-to-Hidden Weights and Biases for j := 0 to FHiddenSize - 1 do begin for i := 0 to FInputSize - 1 do FWeightsIH[i][j] := FWeightsIH[i][j] + Inputs[i] * HiddenGradients[j]; FBiasesH[j] := FBiasesH[j] + HiddenGradients[j]; end; end; function TNeuralNetwork.Predict(const Inputs: TVector): TVector; begin ForwardPropagate(Inputs); Result := FOutputActivation; end; { Main Execution Program } var Brain: TNeuralNetwork; XOR_Inputs: array[0..3] of TVector; XOR_Targets: array[0..3] of TVector; Epoch, i: Integer; Outputs: TVector; begin // Define dataset for the XOR Gate problem XOR_Inputs[0] := TVector.Create(0.0, 0.0); XOR_Targets[0] := TVector.Create(0.0); XOR_Inputs[1] := TVector.Create(0.0, 1.0); XOR_Targets[1] := TVector.Create(1.0); XOR_Inputs[2] := TVector.Create(1.0, 0.0); XOR_Targets[2] := TVector.Create(1.0); XOR_Inputs[3] := TVector.Create(1.0, 1.0); XOR_Targets[3] := TVector.Create(0.0); // Instantiating the AI: 2 inputs, 3 hidden neurons, 1 output, learning rate = 0.5 Brain := TNeuralNetwork.Create(2, 3, 1, 0.5); try Writeln('Training the AI model to learn XOR...'); // Train for 20,000 iterations (epochs) for Epoch := 1 to 20000 do begin for i := 0 to 3 do begin Brain.ForwardPropagate(XOR_Inputs[i]); Brain.BackPropagate(XOR_Inputs[i], XOR_Targets[i]); end; end; Writeln('Training Complete! Testing predictions:'); Writeln('-------------------------------------'); for i := 0 to 3 do begin Outputs := Brain.Predict(XOR_Inputs[i]); Writeln(Format('Input: [%.0f, %.0f] -> Target: %.0f -> AI Prediction: %.4f', [XOR_Inputs[i][0], XOR_Inputs[i][1], XOR_Targets[i][0], Outputs[0]])); end; finally Brain.Free; end; Readln; end.