Artificial neural network with 2-layers and backpropagation

Share your advanced PureBasic knowledge/code with the community.
BalrogSoft
Enthusiast
Enthusiast
Posts: 203
Joined: Sat Apr 26, 2003 6:33 pm
Location: Spain
Contact:

Artificial neural network with 2-layers and backpropagation

Post by BalrogSoft »

Code updated For 5.20+

Hi, i made some procedures to use artifial neural networks with two layers, Input and Hidden layer with backpropagation, it's better than one layer ann's because it can learn some problems that one layer ann's can't, a one layer ann can't learn the xor function, a two layers ann can learn this function.

Code: Select all

; Artificial neural network example by Balrog Soft
; Two layers with backprogpagation 

Global NUM_INPUT, NUM_OUTPUT, NUM_HIDDEN, NUM_NETWORK

NUM_INPUT = 2
NUM_OUTPUT = 1
NUM_HIDDEN = 4
NUM_NETWORK = 1

Dim patternin(NUM_INPUT-1)
Dim patternout(NUM_OUTPUT-1)

    Global Dim W_IN_HIDDEN.f(NUM_NETWORK-1, NUM_INPUT-1, NUM_HIDDEN-1)
    Global Dim W_HIDDEN_OUT.f(NUM_NETWORK-1, NUM_HIDDEN-1, NUM_OUTPUT-1)
    Global Dim N_IN.f(NUM_NETWORK-1, NUM_INPUT-1)
    Global Dim N_HIDDEN.f(NUM_NETWORK-1, NUM_HIDDEN-1)
    Global Dim N_OUT.f(NUM_NETWORK-1, NUM_OUTPUT-1)
    Global Dim N_TEACH.f(NUM_NETWORK-1, NUM_OUTPUT-1)
    Global Dim E_HIDDEN.f(NUM_NETWORK-1, NUM_HIDDEN-1)
    Global Dim E_OUT.f(NUM_NETWORK-1, NUM_OUTPUT-1)
    Global Dim LEARN.f(NUM_NETWORK-1)

#e=2.71828182

Procedure Init_Network(n,i,h,o) 
 NUM_NETWORK = n
 NUM_INPUT = i
 NUM_OUTPUT = o
 NUM_HIDDEN = h 

 Dim patternin(NUM_INPUT-1)
 Dim patternout(NUM_OUTPUT-1)

 Dim W_IN_HIDDEN.f(NUM_NETWORK-1, NUM_INPUT-1, NUM_HIDDEN-1) 
 Dim W_HIDDEN_OUT.f(NUM_NETWORK-1, NUM_HIDDEN-1, NUM_OUTPUT-1)
 Dim N_IN.f(NUM_NETWORK-1, NUM_INPUT-1) 
 Dim N_HIDDEN.f(NUM_NETWORK-1, NUM_HIDDEN-1) 
 Dim N_OUT.f(NUM_NETWORK-1, NUM_OUTPUT-1)
 Dim N_TEACH.f(NUM_NETWORK-1, NUM_OUTPUT-1) 
 Dim E_HIDDEN.f(NUM_NETWORK-1, NUM_HIDDEN-1)
 Dim E_OUT.f(NUM_NETWORK-1, NUM_OUTPUT-1)
 Dim LEARN.f(NUM_NETWORK-1)
 For n=0 To NUM_NETWORK-1
 For h=0 To NUM_HIDDEN-1 
   For o=0 To NUM_OUTPUT-1
    W_HIDDEN_OUT(n, h, o) =(Random(5)-3)
   Next o
  Next h
  For i=0 To NUM_INPUT-1
   For h=0 To NUM_HIDDEN-1
    W_IN_HIDDEN(n, i, h) =(Random(5)-3) 
   Next h
  Next i
 Next n
EndProcedure


Procedure Set_Input(n, i, value.f)
  N_IN(n, i) = value.f
EndProcedure 

Procedure Set_Output(n, o, value.f)
  N_TEACH(n, o) = value.f
EndProcedure 

Procedure.f f_logic(X.f)

 ret.f = 0

 ret = 1 / (1 + Pow(#e,-x))

 ProcedureReturn ret
EndProcedure

Procedure Calculate_Network(n)

 For h=0 To NUM_HIDDEN-1
  N_HIDDEN(n,h) = 0.0
 Next
 
 For o=0 To NUM_OUTPUT-1
  N_OUT(n,o) = 0.0
 Next

 For h=0 To NUM_HIDDEN-1
  For i=0 To NUM_INPUT-1
   N_HIDDEN(n,h) + (N_IN(n,i) * W_IN_HIDDEN(n,i, h))
  Next i
  N_HIDDEN(n,h) = f_logic(N_HIDDEN(n,h))
 Next h

 For o=0 To NUM_OUTPUT-1
  For h=0 To NUM_HIDDEN-1
   N_OUT(n,o) + (N_HIDDEN(n,h) * W_HIDDEN_OUT(n,h, o))
  Next h
  N_OUT(n,o) = f_logic(N_OUT(n,o))
 Next o
EndProcedure

Procedure Calculate_Errors(n)
 err.f

 For o=0 To NUM_OUTPUT-1
  E_OUT(n, o) = (N_TEACH(n, o) - N_OUT(n, o))
 Next o
 
 For h=0 To NUM_HIDDEN-1
  err = 0.0
  For o=0 To NUM_OUTPUT-1
   err + (E_OUT(n, o) * W_HIDDEN_OUT(n, h, o))
  Next o
  E_HIDDEN(n, h) = N_HIDDEN(n, h) * (1 - N_HIDDEN(n, h)) * err
 Next h
EndProcedure

Procedure Train_Network(n)
  For h=0 To NUM_HIDDEN-1
   For o=0 To NUM_OUTPUT-1
    W_HIDDEN_OUT(n, h, o) + (LEARN(n) * N_HIDDEN(n, h) * E_OUT(n, o))
   Next o
  Next h
  For i=0 To NUM_INPUT-1
   For h=0 To NUM_HIDDEN-1
    W_IN_HIDDEN(n, i, h) + (LEARN(n) * N_IN(n, i) * E_HIDDEN(n, h)) 
   Next h
  Next i
EndProcedure

Procedure.f Get_Network_Output(n, o)
  ProcedureReturn N_OUT(n, o)
EndProcedure

Procedure Learn_Constant(n,cte.f)
LEARN(n)=cte
EndProcedure

OpenConsole()

Init_Network(1, 2, 4, 1)

Learn_Constant(0, 0.45)

For RP=1 To 2000
  Inp$=""
  For In=0 To 1
    InputN.f=Random(1)
    Inp.l=InputN
    ;- Set random inputs
    Set_Input(0,In,InputN)
    Inp$+Str(Inp)
  Next In
  
  ; here you must put the combinations that must have a 1.0 output.
  If Inp$="11" Or Inp$="10"
    CorrectOutput.f=1.0
  Else
    CorrectOutput.f=0.0
  EndIf
  Set_Output(0,0,CorrectOutput)
  ; and get an Output #TRUE or #FALSE
  Calculate_Network(0)

  Calculate_Errors(0)
  
  Train_Network(0)

  output.f=Get_Network_Output(0,0)
  If output>=0.5
    PrintN("I: "+Inp$+" - O: 1 - "+StrF(output.f))
  Else
    PrintN("I: "+Inp$+" - O: 0 - "+StrF(output.f))
  EndIf
  Input()
Next RP
Input()

CloseConsole()
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

LOL: :D
I was a day faster 8) :
http://www.robsite.de/php/pureboard/vie ... =2589#2589

BTW: Nice work!

greetz
remi
Athlon64 3700+, 1024MB Ram, Radeon X1600
dmoc
Enthusiast
Enthusiast
Posts: 739
Joined: Sat Apr 26, 2003 12:40 am

Post by dmoc »

Be interesting to hear what you have used this code for?
Post Reply