UNIT BP_unit; { This Unit implements the necessary functions for modelling back- propagation artificial neural network architectures. } { Copyright 1989 by Wesley R. Elsberry. All rights reserved. Commercial use of this software is prohibited without written consent of the author. For information, bug reports, and updates contact Wesley R. Elsberry 528 Chambers Creek Drive South Everman, Texas 76140 Telephone: (817) 551-7018 } INTERFACE USES DOS, Struct, ANN; CONST mach_inf = 1E37; exp_max = 80.0; TAB = ^I; Debug : BOOLEAN = FALSE; TYPE REAL = SINGLE; file_string_ = STRING; node_type_ = (Input,hidden,Output); weight_ptr_ = ^weight_; weight_ = RECORD w, dw : REAL; END; vector_node_ptr_ = ^vector_node_; vector_node_ = RECORD V : REAL; END; sptr_ = ^STRING; data_rec_ptr_ = ^data_rec_; data_rec_ = RECORD s : sptr_; n : data_rec_ptr_; END; weight_node_ptr_ = ^weight_node_; weight_node_ = RECORD connect : BOOLEAN; w, dw, ldw : REAL; END; BP_net_ptr_ = ^BP_net_; BP_node_ptr_ = ^BP_node_; BP_net_ = RECORD vs, ve : DVE_ptr_; {node vector start and vector end} ws : DVE_ptr_; {weight array} learning_rate : REAL; alpha : REAL; {factor for momentum term} vi : DVE_ptr_; {input vector} vos, voe : DVE_ptr_; {output vector} vts, vte : DVE_ptr_; {training vector} n_input, n_hidden, n_output : WORD; maxerr : REAL; errtol : REAL; data_fname : file_string_; data_f : TEXT; training_iterations : INTEGER; out_fname : file_string_; out_f : TEXT; wt_fname : file_string_; wt_f : TEXT; END; BP_node_ = RECORD nt : node_type_; {Input, hidden, or output} loc : WORD; ni : REAL; {net input value} delta : REAL; {delta value for node} base : REAL; range : REAL; theta : REAL; dtheta, ldtheta : REAL; fw, bw : DVE_ptr_; {points to entries in weight_matrix} END; PROCEDURE Dump_BP_net_weights (VAR BPN : BP_net_; VAR Fname : STRING); {Save weights and node bias unit values to a file} PROCEDURE Set_BP_net_weights_from_file (VAR BPN : BP_net_; VAR Fname : STRING); {Restore weights and node bias unit values from a file} PROCEDURE BP_set_net_connects_from_file (VAR BPN : BP_net_; VAR Fname : STRING); {Sets network connectivity values from a file} PROCEDURE Setup_BP_net (VAR BPN : BP_net_;VAR Fname : STRING); {Get data values from a text file to set up basic BP constants, sizes, and other necessary information, or query user if filename is not valid.} PROCEDURE Set_Input_vector_from_file (VAR BPN : BP_net_); {Get data values from a text file to fill input vector.} PROCEDURE Set_Training_vector_from_file (VAR BPN : BP_net_); {Get data values from a text file to fill training vector.} PROCEDURE BP_Feed_forward (VAR BPN : BP_net_); {Present values to network and propagate values forward, set the output vector.} PROCEDURE BP_train_presentation (VAR BPN : BP_net_); {Present values to network, propagate forward, set output, compare output to training, back-propagate, collect statistics but do not change weights.} PROCEDURE BP_train_and_change (VAR BPN : BP_net_); {Present values to network, propagate forward, set output, compare output to training, back-propagate, collect statistics, change weights, and reset statistic variables.} PROCEDURE BP_change (VAR BPN : BP_net_); {Change weights using current statistics and reset statistics.} PROCEDURE BP_dump_net (VAR BPN : BP_net_); {Dump net parameters, node activities, and weights for inspection.} FUNCTION BP_net_error (VAR BPN : BP_net_):REAL; {Returns the largest error from the output nodes} PROCEDURE Display_weights (BPN : BP_net_); {Display of the current weight values for the network} {----------------------------------------------------------------------} IMPLEMENTATION {----------------------------------------------------------------------} {Private, internal functions} FUNCTION max (r1, r2 : REAL):REAL; BEGIN IF r1 >= r2 THEN max := r1 ELSE max := r2; END; {----------------------------------------------------------------------} PROCEDURE Dump_BP_net_weights (VAR BPN : BP_net_; VAR Fname : STRING); {Save weights and node bias unit values to a file} { Preface vector length with !V Preface weight vectors with !W Preface bias unit vector with !T } TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR ii, jj, m, n : WORD; inch : CHAR; done : BOOLEAN; tp1 : DVE_ptr_; ss : STRING; BEGIN n := BPN.n_input + BPN.n_hidden + BPN.n_output; (* ss := FSEARCH(Fname,GETENV('PATH')); IF LENGTH(ss) = 0 THEN BEGIN WRITELN('**ERROR** File does not exist'); EXIT; END; *) BPN.wt_fname := Fname; Assign(BPN.wt_f,Fname); Rewrite(BPN.wt_f); done := FALSE; {Write vector length} Writeln(BPN.wt_f,'!V ',n:1); FOR jj := 1 TO n DO BEGIN Write(BPN.wt_f,'!W '); FOR ii := 1 TO n DO BEGIN tp1 := Find_element_matrix(ii,jj,BPN.ws); IF wnp_(tp1^.dptr)^.connect THEN Write(BPN.wt_f,wnp_(tp1^.dptr)^.w: 4:4,' ') ELSE Write(BPN.wt_f,0.0:4:4,' '); END; Writeln(BPN.wt_f); END; Write(BPN.wt_f,'!T '); FOR ii := 1 TO n DO BEGIN tp1 := Find_element_DVE(ii,BPN.vs); Write(BPN.wt_f,bpnp_(tp1^.dptr)^.theta:4:4,' '); END; Writeln(BPN.wt_f); Writeln(BPN.wt_f,'!Z '); Close(BPN.wt_f); END; {Dump_BP_net_weights} PROCEDURE Set_BP_net_weights_from_file (VAR BPN : BP_net_; VAR Fname : STRING); {Restore weights and node bias unit values from a file} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR ii, jj, m, n : WORD; rr : REAL; tp1, wp1, wp2 : DVE_ptr_; inch : CHAR; done : BOOLEAN; ss : STRING; BEGIN {} n := BPN.n_input + BPN.n_hidden + BPN.n_output; ss := FSEARCH (Fname,GETENV('PATH')); IF (Length(ss) = 0) THEN BEGIN Writeln ('**ERROR** File does not exist'); EXIT; END; Assign (BPN.wt_f,ss); Reset (BPN.wt_f); done := FALSE; {Find vector length, compare to net vector length} REPEAT REPEAT {find command} Read (BPN.wt_f,inch); UNTIL (inch = '!') OR Eof(BPN.wt_f); {} Read (BPN.wt_f,inch); UNTIL (UpCase (inch) = 'V') OR Eof (BPN.wt_f); IF Eof (BPN.wt_f) THEN BEGIN EXIT; END; Read (BPN.wt_f,inch); Read (BPN.wt_f,m); IF (m <> n) THEN BEGIN {Vector lengths don't match, quit} EXIT; END; wp1 := BPN.ws; REPEAT {get net params} REPEAT {find command} Read (BPN.wt_f,inch); UNTIL (inch = '!'); {} Read (BPN.wt_f,inch); CASE UpCase (inch) OF 'T' : BEGIN {get bias values} Read (BPN.data_f, inch); FOR ii := 1 TO n DO BEGIN tp1 := Find_element_DVE (ii,BPN.vs); Read (BPN.wt_f,rr); bpnp_(tp1^.dptr)^.theta := rr; END; END; {} 'W' : BEGIN {get weights} IF wp1 <> NIL THEN BEGIN Read (BPN.data_f,inch); FOR ii := 1 TO n DO BEGIN wp2 := Find_element_DVE (ii,wp1); Read (BPN.wt_f,rr); wnp_(wp2^.dptr)^.w := rr; END; {For ii} wp1 := wp1^.down; END; END; {} 'Z' : DONE := TRUE; ELSE BEGIN DONE := TRUE; END; END; UNTIL (done OR Eof (BPN.wt_f)); {} END; {set_BP_net_weights_from_file} PROCEDURE BP_set_net_connects_from_file (VAR BPN : BP_net_; VAR Fname : STRING); {Sets network connectivity values from a file} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR ii, jj, kk, m, n : WORD; tp1, wp1, wp2 : DVE_ptr_; inch : CHAR; done : BOOLEAN; ss : STRING; cfile : TEXT; BEGIN {} n := BPN.n_input + BPN.n_hidden + BPN.n_output; ss := FSEARCH (Fname,GETENV('PATH')); IF (Length(ss) = 0) THEN BEGIN Writeln ('**ERROR** File does not exist'); EXIT; END; Assign (cfile,ss); Reset (cfile); done := FALSE; {Find vector length, compare to net vector length} REPEAT REPEAT {find command} Read (cfile,inch); UNTIL (inch = '!') OR Eof(cfile); {} Read (cfile,inch); UNTIL (UpCase (inch) = 'V') OR Eof (cfile); IF Eof (cfile) THEN BEGIN EXIT; END; Read (cfile,inch); Read (cfile,m); IF (m <> n) THEN BEGIN {Vector lengths don't match, quit} EXIT; END; wp1 := BPN.ws; REPEAT {get net params} REPEAT {find command} Read (cfile,inch); UNTIL (inch = '!'); {} Read (cfile,inch); CASE UpCase (inch) OF 'C' : BEGIN {get weights} IF wp1 <> NIL THEN BEGIN Read (cfile,inch); FOR ii := 1 TO n DO BEGIN wp2 := Find_element_DVE (ii,wp1); Read (cfile,kk); wnp_(wp2^.dptr)^.connect := (kk = 1); END; {For ii} wp1 := wp1^.down; END; END; {} 'Z' : DONE := TRUE; ELSE BEGIN DONE := TRUE; END; END; UNTIL (done OR Eof (cfile)); {} END; {BP_set_net_connects_from_file} PROCEDURE Dump_node (net : BP_net_; node : BP_node_ptr_); TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; BEGIN IF (debug) THEN {} BEGIN Writeln ('DUMP_NODE'); Writeln (NET.OUT_F,'DUMP_NODE'); END; IF (node <> NIL) THEN BEGIN CASE node^.nt OF Input : BEGIN Write (net.out_f,'INPUT'); Write ('INPUT'); END; hidden : BEGIN Write (net.out_f,'HIDDEN'); Write ('HIDDEN'); END; Output : BEGIN Write (net.out_f,'OUTPUT'); Write ('OUTPUT'); END; END; Write (net.out_f,tab,'LOC : ',NODE^.LOC); Write ('LOC : ',NODE^.LOC); Writeln (net.out_f,tab,'ADDR : ',Seg(NODE),':',Ofs(NODE)); Writeln (tab,'ADDR : ',Seg(NODE),':',Ofs(NODE)); Write (net.out_f,'NI : ',node^.ni:8); Write ('NI : ',node^.ni:8); Writeln (net.out_f,tab,'DELTA : ',NODE^.DELTA:8); Writeln (tab,'DELTA : ',NODE^.DELTA:8); Write (net.out_f,'BASE : ',NODE^.BASE:8); Write ('BASE : ',NODE^.BASE:8); Writeln (net.out_f,tab,'RANGE : ',NODE^.RANGE:8); Writeln (tab,'RANGE : ',NODE^.RANGE:8); Write (net.out_f,'THETA : ',NODE^.THETA:8); Write ('THETA : ',NODE^.THETA:8); Writeln (net.out_f,tab,'DTHETA : ',NODE^.DTHETA:8,tab, 'LDTHETA : ', NODE^.LDTHETA:8); Writeln (tab,'DTHETA : ',NODE^.DTHETA:8,tab,'LDTHETA : ',NODE^. LDTHETA:8); Writeln (net.out_f,'FW : ',Seg(NODE^.FW),':', Ofs(NODE^.FW), tab,'BW : ', Seg(NODE^.BW),':',Ofs(NODE^.BW)); Writeln ('FW : ',Seg(NODE^.FW),':', Ofs(NODE^.FW),tab,'BW : ', Seg(NODE^.BW),':',Ofs(NODE^.BW)); Writeln (net.out_f); Writeln; END; IF (debug) THEN BEGIN Writeln ('END DUMP_NODE'); Writeln (NET.OUT_F,'END DUMP_NODE'); END; END; PROCEDURE Display_weights (BPN : BP_net_); {Display of the current weight values for the network} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR twpd, twpa : DVE_ptr_; wptr : DVE_ptr_; BEGIN {} IF debug THEN BEGIN Writeln ('DISPLAY_WEIGHTS'); Writeln (BPN.OUT_F,'DISPLAY_WEIGHTS'); END; twpd := BPN.ws; twpa := BPN.ws; WHILE (twpd <> NIL) DO BEGIN{} WHILE (twpa <> NIL) DO BEGIN {} wptr := twpa^.dptr; IF (wnp_(wptr)^.connect) THEN BEGIN Write (BPN.out_f,wnp_(wptr)^.w:5:1,' '); Write (wnp_(wptr)^.w:5:1,' '); END ELSE {} BEGIN Write (BPN.out_f,' --- '); Write (' --- '); END; twpa := twpa^.right; END; {} Writeln (BPN.out_f); Writeln ; twpd := twpd^.down; twpa := twpd; END; {} Writeln (BPN.out_f,'End of weights'); Writeln ('End of weights'); Writeln; Writeln; IF (debug) THEN {} BEGIN Writeln ('END DISPLAY_WEIGHTS'); Writeln (BPN.OUT_F,'END DISPLAY_WEIGHTS'); END; Flush (BPN.out_f); END; {} PROCEDURE Display_Vector (vp : DVE_ptr_; N : INTEGER; NET : BP_net_); {} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR ii : INTEGER; vptr : vector_node_ptr_; BEGIN {} IF debug THEN BEGIN Writeln ('DISPLAY_VECTOR'); Writeln (NET.OUT_F,'DISPLAY_VECTOR'); END; FOR II := 1 TO N DO BEGIN {} vptr := vp^.dptr; Write (net.out_f,vptr^.V:8,' '); Write (vptr^.V:8,' '); vp := vp^.right; END; Writeln (net.out_f); Writeln; IF (debug) THEN {} BEGIN Writeln ('END DISPLAY_VECTOR'); Writeln (NET.OUT_F,'END DISPLAY_VECTOR'); END; END; {} FUNCTION BP_net_error (VAR BPN : BP_net_):REAL; {Returns the largest error from the output nodes} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR rr : REAL; tp, vp1, vp2 : DVE_ptr_; ii, n : INTEGER; BEGIN rr := 0; n := BPN.n_input + BPN.n_hidden + BPN.n_output; vp1 := BPN.vos; vp2 := BPN.vts; FOR ii := 1 TO BPN.n_output DO BEGIN IF (vp1^.dptr <> NIL) AND (vp2^.dptr <> NIL) THEN BEGIN rr := max (ABS(rr), ABS(vnp_(vp2^.dptr)^.v - vnp_(vp1^.dptr)^.v)); IF vp1^.right <> NIL THEN vp1 := vp1^.right; IF vp2^.right <> NIL THEN vp2 := vp2^.right; END ELSE BEGIN END; END; BP_net_error := ABS(rr); END; PROCEDURE Allocate_IO_vectors (VAR net : BP_net_); TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR ii, N : WORD; BEGIN IF debug THEN BEGIN Writeln ('ALLOCATE_IO_VECTORS'); Writeln (NET.OUT_F,'ALLOCATE_IO_VECTORS'); END; N := net.n_input + net.n_hidden + net.n_output; net.vi := Create_DVE_vector (net.n_input, SizeOf(vector_node_)); net.vos := Create_DVE_vector (net.n_output, SizeOf(vector_node_)); net.vts := Create_DVE_vector (net.n_output, SizeOf(vector_node_)); net.voe := Find_element_DVE (net.n_output, net.vos); net.vte := Find_element_DVE (net.n_output, net.vts); IF (debug) THEN {} BEGIN Writeln ('END ALLOCATE_IO_VECTORS'); Writeln (NET.OUT_F,'END ALLOCATE_IO_VECTORS'); END; END; PROCEDURE Allocate_node_vector (VAR net : BP_net_); TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR ii, cnt, N : INTEGER; Temp : BP_node_ptr_; nptr : DVE_ptr_; low, high : REAL; ns : BP_node_; BEGIN cnt := 1; N := net.n_input + net.n_hidden + net.n_output; IF debug THEN BEGIN Writeln ('ALLOCATE_NODE_VECTOR'); Writeln (NET.OUT_F,'ALLOCATE_NODE_VECTOR'); END; net.vs := Create_DVE_vector (net.n_input, SizeOf (BP_node_)); net.ve := Find_element_DVE (net.n_input, net.vs); nptr := net.vs; FOR ii := 1 TO net.n_input DO BEGIN temp := nptr^.dptr; Temp^.loc := cnt; cnt := cnt + 1; Temp^.nt := Input; {set node type} Temp^.ni := 0; {init net input} Temp^.fw := NIL; {no weight yet} Temp^.bw := NIL; {no weight yet} Temp^.delta := 0; Temp^.base := 0; Temp^.range := 1; Temp^.theta := 0; Temp^.dtheta := 0; Temp^.ldtheta := 0; nptr := nptr^.right; END; {FOR} net.ve^.right := Create_DVE_vector (net.n_hidden, SizeOf(BP_node_)); net.ve^.right^.left := net.ve; nptr := net.ve^.right; net.ve := Find_element_DVE (net.n_input + net.n_hidden, net.vs); FOR II := 1 TO net.n_hidden DO BEGIN temp := nptr^.dptr; Temp^.loc := cnt; cnt := cnt + 1; Temp^.nt := hidden; {set node type} Temp^.ni := 0; {init net input} Temp^.fw := NIL; {no weight yet} Temp^.bw := NIL; {no weight yet} Temp^.delta := 0; Temp^.base := 0; Temp^.range := 1; Temp^.theta := gaussian_noise (0,0.25); Temp^.dtheta := 0; Temp^.ldtheta := 0; nptr := nptr^.right; END; net.ve^.right := Create_DVE_vector (net.n_output, SizeOf(BP_node_)); net.ve^.right^.left := net.ve; nptr := net.ve^.right; net.ve := Find_element_DVE (net.n_input + net.n_hidden + net.n_output,net.vs); FOR II := 1 TO net.n_output DO BEGIN temp := nptr^.dptr; Temp^.loc := cnt; cnt := cnt + 1; Temp^.nt := Output; {set node type} Temp^.ni := 0; {init net input} Temp^.fw := NIL; {no weight yet} Temp^.bw := NIL; {no weight yet} Temp^.delta := 0; Temp^.base := 0 {low}; Temp^.range := 1 {high - low}; Temp^.theta := gaussian_noise (0,0.25); Temp^.dtheta := 0; Temp^.ldtheta := 0; nptr := nptr^.right; END; IF (debug) THEN BEGIN Writeln ('END ALLOCATE_NODE_VECTOR'); Writeln (NET.OUT_F,'END ALLOCATE_NODE_VECTOR'); END; END; PROCEDURE Allocate_weight_matrix (VAR net : BP_net_); TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR ii, jj, N : WORD; temp : DVE_ptr_; tl, tc, tls, tcs : weight_node_ptr_; Vt : Vector_node_ptr_; cnt : INTEGER; BEGIN IF debug THEN BEGIN Writeln ('ALLOCATE_WEIGHT_MATRIX'); Writeln (NET.OUT_F,'ALLOCATE_WEIGHT_MATRIX'); END; cnt := 1; N := net.n_input + net.n_hidden + net.n_output; net.ws := create_matrix (n,n,SizeOf(weight_node_)); FOR ii := 1 TO n DO BEGIN FOR jj := 1 TO n DO BEGIN temp := Find_element_matrix(ii, jj, net.ws); IF temp <> NIL THEN BEGIN wnp_(temp^.dptr)^.connect := FALSE; wnp_(temp^.dptr)^.w := 2 * Random - 1; {random weights, -1 < w < 1 } wnp_(temp^.dptr)^.dw := 0; wnp_(temp^.dptr)^.ldw := 0; END; {IF temp <> NIL} END; END; IF (debug) THEN {} BEGIN Writeln ('END ALLOCATE_WEIGHT_MATRIX'); Writeln (NET.OUT_F,'END ALLOCATE_WEIGHT_MATRIX'); END; END; PROCEDURE Link_weights_to_nodes (VAR net : BP_net_); TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR Start, TempD, TempA : DVE_ptr_; Vt : DVE_ptr_; ii, jj, N : INTEGER; BEGIN {Link to node vector} IF debug THEN BEGIN Writeln ('LINK_WEIGHTS_TO_NODES'); Writeln (NET.OUT_F,'LINK_WEIGHTS_TO_NODES'); END; N := net.n_input + net.n_hidden + net.n_output; Start := net.ws; TempD := Start; TempA := Start; Vt := net.vs; FOR ii := 1 TO N DO BEGIN bpnp_(Vt^.dptr)^.fw := TempD; TempD := TempD^.down; bpnp_(Vt^.dptr)^.bw := TempA; TempA := TempA^.right; Vt := Vt^.right; END; IF (debug) THEN {} BEGIN Writeln ('END LINK_WEIGHTS_TO_NODES'); Writeln (NET.OUT_F,'END LINK_WEIGHTS_TO_NODES'); END; END; {Link_weights_to_nodes} PROCEDURE Display_node_type (VAR net : BP_net_); {} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR tp : DVE_ptr_; N, ii : INTEGER; BEGIN {} IF debug THEN BEGIN Writeln ('DISPLAY_NODE_TYPE'); Writeln (NET.OUT_F,'DISPLAY_NODE_TYPE'); END; tp := net.vs; N := net.n_input + net.n_hidden + net.n_output; FOR ii := 1 TO n DO BEGIN {} CASE bpnp_(tp^.dptr)^.nt OF Input : BEGIN Write (net.out_f,'I'); Write ('I'); END; hidden : BEGIN Write (net.out_f,'H'); Write ('H'); END; Output : BEGIN Write (net.out_f,'O'); Write ('O'); END; END; TP := tp^.right; END; {} Writeln (net.out_f); Writeln ; IF (debug) THEN {} BEGIN Writeln ('END DISPLAY_NODE_TYPE'); Writeln (NET.OUT_F,'END DISPLAY_NODE_TYPE'); END; END; {} PROCEDURE Display_node_deltas (VAR net : BP_net_); {} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR tp : DVE_ptr_; N, ii : INTEGER; BEGIN {} IF debug THEN BEGIN Writeln ('DISPLAY_NODE_DELTAS'); Writeln (NET.OUT_F,'DISPLAY_NODE_DELTAS'); END; tp := net.vs; N := net.n_input + net.n_hidden + net.n_output; FOR ii := 1 TO n DO BEGIN {} TP := tp^.right; END; {} IF (debug) THEN {} BEGIN Writeln ('END DISPLAY_NODE_DELTAS'); Writeln (NET.OUT_F,'END DISPLAY_NODE_DELTAS'); END; END; {} PROCEDURE set_connectivity (VAR net : BP_net_); TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; VAR wpt : DVE_ptr_; tvd, tva : DVE_ptr_; ii, jj, n : INTEGER; BEGIN IF debug THEN BEGIN Writeln ('SET_CONNECTIVITY'); Writeln (NET.OUT_F,'SET_CONNECTIVITY'); END; n := net.n_input + net.n_hidden + net.n_output; tvd := net.vs; {beginning of node vector} tva := net.vs; wpt := bpnp_(tvd^.dptr)^.fw; {display_node_type (net);} FOR ii := 1 TO n DO BEGIN FOR jj := 1 TO n DO BEGIN CASE bpnp_(tvd^.dptr)^.nt OF Input : BEGIN wnp_(wpt^.dptr)^.connect := FALSE; END; hidden : BEGIN IF (bpnp_(tva^.dptr)^.nt = Input) THEN BEGIN wnp_(wpt^.dptr)^.connect := TRUE; END ELSE BEGIN wnp_(wpt^.dptr)^.connect := FALSE; END; END; Output : BEGIN IF (bpnp_(tva^.dptr)^.nt = hidden) THEN BEGIN wnp_(wpt^.dptr)^.connect := TRUE; END ELSE BEGIN wnp_(wpt^.dptr)^.connect := FALSE; END; END; END; {case} wpt := wpt^.right; tva := tva^.right; END; tvd := tvd^.right; tva := net.vs; wpt := bpnp_(tvd^.dptr)^.fw; END; IF (debug) THEN {} BEGIN Writeln ('END SET_CONNECTIVITY'); Writeln (NET.OUT_F,'END SET_CONNECTIVITY'); END; END; PROCEDURE Display_output (VAR net : BP_net_); {} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; BEGIN {} IF debug THEN BEGIN Writeln ('DISPLAY_OUTPUT'); Writeln (NET.OUT_F,'DISPLAY_OUTPUT'); END; display_vector (net.vos,net.n_output,net); IF (debug) THEN {} BEGIN Writeln ('END DISPLAY_OUTPUT'); Writeln (NET.OUT_F,'END DISPLAY_OUTPUT'); END; END; {} FUNCTION BP_error_measure (Output_vector_ptr : DVE_ptr_; Training_vector_ptr : DVE_ptr_; net : BP_net_): REAL; BEGIN END; {BP_error_measure} {----------------------------------------------------------------------} PROCEDURE BP_set_net_defaults (VAR net : BP_net_); {} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; BEGIN {} WITH net DO BEGIN {} vs := NIL; ve := NIL; ws := NIL; vi := NIL; vos := NIL; voe := NIL; vts := NIL; vte := NIL; maxerr := 0.2; errtol := 0.1; learning_rate := 0.5; alpha := 0.9; {factor for momentum term} n_input := 1; n_hidden := 1; n_output := 1; { data_fname := 'BP.DAT';} training_iterations := 1; out_fname := 'BP.OUT'; wt_fname := ''; END; {} END; {} PROCEDURE BP_get_net_params_from_user (VAR net : BP_net_); {} TYPE bpnp_ = BP_node_ptr_; wnp_ = weight_node_ptr_; vnp_ = vector_node_ptr_; BEGIN {} Write ('File to output run data to : '); Readln (net.out_fname); Assign (net.out_f,net.out_fname); Rewrite (net.out_f); {learning rate} Write ('Learning rate? : '); Readln (net.learning_rate); Writeln (NET.OUT_F,'Learning rate : ',net.learning_rate:5:3); Writeln ('Learning rate : ',net.learning_rate:5:3); {momentum factor} Write ('Momentum factor? : '); Readln (net.alpha); Writeln (NET.OUT_F,'Momentum factor : ',net.alpha:5:3); Writeln ('Momentum factor : ',net.alpha:5:3); {# of input nodes?} {BP_INPUT_NODES_NUM} Write ('Number of input nodes? : '); Readln (net.n_input); Writeln (NET.OUT_F,'# of input nodes : ',net.n_input:3); Writeln ('# of input nodes : ',net.n_input:3); {# of hidden nodes in vector} Write ('Number of hidden nodes? : '); Readln (net.n_hidden); Writeln (NET.OUT_F,'# of hidden nodes : ',net.n_hidden:3); Writeln ('# of hidden nodes : ',net.n_hidden:3); {# of output nodes} Write ('Number of output nodes? : '); Readln (net.n_output); Writeln (NET.OUT_F,'# of output nodes : ',net.n_output:3); Writeln ('# of output nodes : ',net.n_output:3); {error tolerance} Write ('Error tolerance? : '); Readln (net.errtol); Writeln (NET.OUT_F,'Error tolerance : ',net.errtol:5:3); Writeln ('Error tolerance : ',net.errtol:5:3); Writeln; Write ('Name of data file : '); Readln (net.data_fname); Writeln (NET.OUT_F,'Data file : ',net.data_fname:15); Writeln ('Data file : ',net.data_fname:15); Write ('Number of training runs? : '); Readln (net.training_iterations); Writeln (NET.OUT_F,'# of iterations : ', net.training_iterations:3); Writeln ('# of iterations : ',net.training_iterations:3); Writeln; END; {} PROCEDURE BP_set_net_params_from_file (VAR net : BP_net_; VAR Fname : STRING); { Use the following format for data entries in this section: !