program FANN_NeuralLogicTrainer_EKON25; //interface {uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, FannNetwork, StdCtrls; } //http://leenissen.dk/fann/wp/2015/11/fann-in-research/ Const TRAIN_EPOCHS = 5000; PERF_GATE = 0.85; type TForm1 = TForm; //) var btnTrain: TBitbtn; LblError: TLabel; lblMSE, lblTarget: TLabel; edtRule: TEdit; btnRun: TBitbtn; memoXor: TMemo; btnBuild: TBitBtn; epochs: TProgressBar; NN: TFannNetwork; procedure TForm1btnBuildClick(Sender: TObject); forward; procedure TForm1btnTrainClick(Sender: TObject); forward; procedure TForm1btnRunClick(Sender: TObject); forward; //private { Private declarations } //public { Public declarations } //end; var Form1: TForm1; //implementation //{$R *.dfm} procedure TForm1btnTrainClick(Sender: TObject); var inputs: array [0..1] of single; outpts: array [0..0] of single; //outputs: array of single; e,i,j: integer; mse: single; begin //Train the neural network epochs MemoXOR.Lines.Clear; for e:= 1 to TRAIN_EPOCHS do begin //Train n epochs epochs.Position:= e div 1; for i:= 0 to 1 do begin for j:= 0 to 1 do begin inputs[0]:=i; inputs[1]:=j; case JStrUpper(trim(edtrule.text)) of 'AND' : outpts[0]:= (i And j); 'NAND': outpts[0]:= 1-(i And j); 'OR' : outpts[0]:= (i Or j); 'XOR' : outpts[0]:= (i XOr j); 'NOR' : outpts[0]:= 1-(i Or j); 'IMP' : outpts[0]:= (i Or (1-j)); 'AEQ' : outpts[0]:= 1-(i XOr j); 'TAU' : outpts[0]:= 1; else outpts[0]:= (i XOr j); end; Mse:=NN.Train(inputs,outpts); if e mod 4 = 0 then lblMse.Caption:=Format('%.4f',[Mse]); Application.ProcessMessages; end; end; if e mod 10 = 0 then MemoXor.Lines.Add(Format('%d error log = %.4f',[e, MSE])); end; ShowMessage('Network Epoch '+itoa(TRAIN_EPOCHS)+' Training Ends...'); Writeln('Network Epoch '+itoa(TRAIN_EPOCHS)+' Training Ends...'); end; procedure TForm1btnRunClick(Sender: TObject); var i,j, perfcnt: integer; perf1: single; inputs: array [0..1] of single; //output: array of fann_type; aoutput: TFann_Type_Array3; begin MemoXOR.Lines.Clear; setlength(aoutput, 4) perf1:= 0.0; perfcnt:= 0; //NN.Run(inputs,aoutput); for i:=0 to 1 do begin for j:=0 to 1 do begin inputs[0]:=i; inputs[1]:=j; // test and predict NN.Run4(inputs,aoutput); MemoXor.Lines.Add(Format('%d '+JStrUpper(trim(edtrule.text)) +' %d = %.3f',[i,j,aOutput[0]])); //writeln(floattostr(nn.learningmometum)) if aOutput[0] > PERF_GATE then begin perf1:= perf1 + aOutput[0]; inc(perfcnt) end; end; end; writeln('Test Score: '+floattostr(perf1 / perfcnt)) MemoXor.Lines.Add(Format('TScore: %.5f',[perf1 / perfcnt])); end; procedure TForm1btnBuildClick(Sender: TObject); begin NN.Build; //btnBuild.Enabled:=false; btnBuild.caption:= 'Rebuild'; MemoXOR.Lines.Clear; BtnTrain.Enabled:=true; btnRun.Enabled:=true; MemoXor.Lines.Add('Build NN with '+itoa(NN.layers.count)+' layers:') for it:= 0 to NN.layers.count-1 do MemoXor.Lines.Add('NN '+itoa(it)+': with '+nn.Layers[it]) end; // Procedure AllBooleanPattern(aX, aY: integer); begin Writeln(#13#10+'************** All Booolean Functions **************'); PrintF('%-26s 01 False',[inttobinbyte(0)]) PrintF('%-26s 02 AND',[inttobinbyte(aX AND aY)]) PrintF('%-26s 03 Inhibit',[inttobinbyte(aX AND NOT aY)]) PrintF('%-26s 04 Prepend',[inttobinbyte(aX)]) PrintF('%-26s 05 Praesect',[inttobinbyte(NOT aX AND aY)]) PrintF('%-26s 06 Postpend',[inttobinbyte(aY)]) PrintF('%-26s 07 XOR',[inttobinbyte(aX XOR aY)]) PrintF('%-26s 08 OR',[inttobinbyte(aX OR aY)]) PrintF('%-26s 09 NOR',[inttobinbyte(NOT(aX OR aY))]) PrintF('%-26s 10 Aequival',[inttobinbyte((NOT aX OR aY)AND(NOT aY OR aX))]) PrintF('%-26s 11 NegY',[inttobinbyte(NOT aY)]) PrintF('%-26s 12 ImplicatY',[inttobinbyte(aX OR NOT aY)]) PrintF('%-26s 13 NegX',[inttobinbyte(NOT aX)]) PrintF('%-26s 14 ImplicatX',[inttobinbyte(NOT aX OR aY)]) PrintF('%-26s 15 NAND',[inttobinbyte(NOT(aX AND aY))]) PrintF('%-26s 16 True',[inttobinbyte(NOT 0)]) end; procedure setNeuralForm; begin Form1:= TForm1.create(self) with form1 do begin Left:= 278; Top:= 151; BorderStyle:= bsSingle formstyle:= fsstayontop; Caption:= 'Python Delphi FANN All Logic Demo' Icon.LoadFromResourceName(HInstance,'ZCUBE'); //TFANNNETWORK ClientHeight:= 280 ClientWidth:= 410 Color:= clBtnFace Font.Charset:= DEFAULT_CHARSET Font.Color:= clWindowText Font.Height:= -11 Font.Name:= 'MS Sans Serif' Font.Style:= [] OldCreateOrder:= False Position:= poScreenCenter PixelsPerInch := 96 //TextHeight := 13 Show; end; LblError:= TLabel.create(form1) with lblerror do begin parent:= form1; setBounds(120, 10, 111,20); Caption:= 'Mean Square Error:' Font.Charset:= DEFAULT_CHARSET Font.Color:= clWindowText Font.size:= 12 Font.Name:= 'MS Sans Serif' Font.Style:= [fsBold] ParentFont:= False end; lblMSE:= TLabel.create(form1) with lblmse do begin parent:= form1; SetBounds(285, 10, 5, 20) Font.Charset:= DEFAULT_CHARSET Font.Color:= clRed Font.size:= 12 Font.Name:= 'MS Sans Serif' Font.Style:= [fsBold] ParentFont:= False end; lbltarget:= TLabel.create(form1) with lbltarget do begin parent:= form1; setbounds(8, 10, 5, 13); caption:= 'TTarget:'; Font.Color:= clgreen; Font.size:= 12; Font.Name:= 'MS Sans Serif' Font.Style:= [fsBold] ParentFont:= False end; edtrule:= TEdit.create(form1) with edtrule do begin parent:= form1; setbounds(8, 40, 105, 30); text:= 'XOR'; Font.Charset:= DEFAULT_CHARSET Font.Color:= clRed Font.size:= 14 Font.Name:= 'MS Sans Serif' ParentFont:= False end; btnBuild:= TBitBtn.create(form1) with btnbuild do begin parent:= form1 setbounds(8, 136, 97, 28); Caption:= 'Build' glyph.LoadFromRes(getHINSTANCE,'TFANNNETWORK'); TabOrder:= 3 OnClick:= @tform1btnBuildClick; end; btnTrain:= TBitBtn.create(form1) with btntrain do begin parent:= form1; setbounds(8, 177, 97, 28); Caption:= 'Train' glyph.LoadFromRes(getHINSTANCE,'VPPLUS'); Enabled:= False TabOrder:= 0 OnClick:= @tform1btnTrainClick; end; btnRun:= TBitBtn.create(form1) with btnrun do begin parent:= form1 setbounds(8, 216, 97, 28); Caption:= 'Test' glyph.LoadFromRes(getHINSTANCE,'TEXTFORMCHECKBOX'); //'VPCHECKPAD'); Enabled:= False TabOrder:= 1 OnClick:= @tform1btnRunClick end; memoXor:= TMemo.create(form1) with memoXor do begin parent:= form1; setbounds(120, 40, 270, 203); font.size:= 14; ReadOnly:= True TabOrder:= 2 end; epochs:= TProgressBar.Create(form1); with epochs do begin parent:= form1; Align:= alBottom; step:= 5; Max:= TRAIN_EPOCHS-300; end; NN:= TFannNetwork.create(self) with NN do begin {Layers.Strings:= ('2' '3' '1') } Layers.add('2') Layers.add('3') Layers.add('1') LearningRate:= 0.699999988079071100 ConnectionRate:= 1.000000000000000000 TrainingAlgorithm:= taFANN_TRAIN_RPROP ActivationFunctionHidden:= afFANN_SIGMOID ActivationFunctionOutput:= afFANN_SIGMOID //Left := 192 //Top := 40 end end; begin //@main setNeuralForm; AllBooleanPattern(10,12); End. Doc and Ref: All Logic Symbols Proposal for Abreviation Symbol: 01 FALSE //Contradiction 02 AND //Conjunction x*y 03 INHIB //Inhibition x*^y 04 PRAEP //Praependence y 05 PRAE //Praesection ^x*y 06 POST //Postpendence x 07 XOR //Exclusive OR x*^y+^x*y 08 OR //Disjunction OR = x+y 09 NOR //Rejection 10 AEQ //Aequivalence x<-->y, ^x*^y+x*y 11 NEGY //YNegation ^y 12 IMPY //YImplication y-->x; x+^y 13 NEGX //Xnegation ^x 14 IMPX //XImplication x-->y; ^x+y 15 NAND //Exclusion 16 TRUE //TRUE Tautologic Output: 00000000000000000000000000000000 01 False 00000000000000000000000000001000 02 AND 00000000000000000000000000000010 03 Inhibit 00000000000000000000000000001010 04 Prepend 00000000000000000000000000000100 05 Praesect 00000000000000000000000000001100 06 Postpend 00000000000000000000000000000110 07 XOR 00000000000000000000000000001110 08 OR 11111111111111111111111111110001 09 NOR 11111111111111111111111111111001 10 Aequival 11111111111111111111111111110011 11 NegY 11111111111111111111111111111011 12 ImplicatY 11111111111111111111111111110101 13 NegX 11111111111111111111111111111101 14 ImplicatX 11111111111111111111111111110111 15 NAND 11111111111111111111111111111111 16 True (A<>B) NOT --> A=B 0 0 0 1 0 0 0 1 1 0 1 0 1 0 1 1 0 1 1 1 Class Doc: procedure SIRegister_TFannNetwork(CL: TPSPascalCompiler); begin //with RegClassS(CL,'TComponent', 'TFannNetwork') do with CL.AddClassN(CL.FindClass('TComponent'),'TFannNetwork') do begin Constructor Create( Aowner : TComponent)'); Procedure Build( )'); Procedure Free'); Procedure UnBuild( )'); Function Train( Input : array of fann_type; Output : array of fann_type) : single'); Procedure TrainOnFile(FileName:String; MaxEpochs:Cardinal;DesiredError: Single)'); Procedure Run(Inputs: array of fann_type; var Outputs : TFann_Type_Array2)'); Procedure Run2(Inputs: array of fann_type; var Outputs : array of fann_type)'); Procedure Run3( Inputs : array of fann_type; var Outputs : TFann_Type_Array3)'); Procedure Run4( Inputs : array of fann_type; var Outputs : TFann_Type_Array3)'); Procedure SaveToFile( FileName : String)'); Procedure LoadFromFile( Filename : string)'); FannObject', 'PFann', iptr); Layers', 'TStrings', iptrw); LearningRate', 'Single', iptrw); ConnectionRate', 'Single', iptrw); LearningMometum', 'single', iptrw); MSE', 'Single', iptr); TrainingAlgorithm', 'TTrainingAlgorithm', iptrw); ActivationFunctionHidden', 'TActivationFunction', iptrw); ActivationFunctionOutput', 'TActivationFunction', iptrw); end; end; //Doc: http://leenissen.dk/fann/wp/language-bindings/