method train input example (alpha :float) =
let loop rep activation =
(* this loop handles layers 2 to n *)
let rec loop2 rep activation =
match rep with
layer :: rest_rep ->
begin
if Array.length layer.(0) != Array.length activation +1 then
failwith "Input Size Error"
else ();
(* add the bias *)
let activation = Array.append [|1.0|] activation in
(* calculate the weighted sums *)
let sums = layer |*| activation in
(* apply transfer functions *)
let output = Array.map sigmoid sums in
(* descend to next layer and get weighted sums of deltas from there*)
let delta_sums = loop2 rest_rep output in
(* calculate deltas from those sums *)
let deltas = Array.mapi (fun i x -> output.(i) *. (1.0-.output.(i))*.x) delta_sums in
(* create array to hold new deltas*)
let new_deltas = Array.make (Array.length activation) 0.0 in
(* calculate the differences*)
let n = Array.length layer in
let m = Array.length (Array.unsafe_get layer 0) in
for i = 0 to n - 1 do
let weightsi = Array.unsafe_get layer i in
let deltai = Array.unsafe_get deltas i in
for j = 0 to m - 1 do
let weightij = Array.unsafe_get weightsi j in
let change = alpha *. deltai *. Array.unsafe_get activation j in
(* get this part of the corresponding new_delta *)
Array.unsafe_set new_deltas j (Array.unsafe_get new_deltas j +. deltai *. weightij);
Array.unsafe_set weightsi j (weightij +. change);
done
done;
(* pass the deltas to caller, but throw away the one for the bias *)
Array.sub new_deltas 1 (Array.length activation - 1)
end
| [] -> Array.mapi (fun i x -> example.(i) -. x) activation
in
(* Special faster case for the first (and most often largest) layer *)
match rep with
layer :: rest_rep ->
begin
if Array.length layer.(0) != Array.length activation +1 then
failwith "Input Size Error"
else ();
(* add the bias *)
let activation = Array.append [|1.0|] activation in
(* calculate the weighted sums *)
let sums = layer |*| activation in
(* apply transfer functions *)
let output = Array.map sigmoid sums in
(* descend to next layer and get weighted sums of deltas from there*)
let delta_sums = loop2 rest_rep output in
(* calculate deltas from those sums *)
let deltas = Array.mapi (fun i x -> output.(i) *. (1.0-.output.(i))*.x) delta_sums in
(* calculate the differences*)
let n = Array.length layer in
let m = Array.length (Array.unsafe_get layer 0) in
for i = 0 to n - 1 do
let weightsi = Array.unsafe_get layer i in
let deltai = Array.unsafe_get deltas i in
for j = 0 to m - 1 do
let weightij = Array.unsafe_get weightsi j in
let change = alpha *. deltai *. Array.unsafe_get activation j in
(* get this part of the corresponding new_delta *)
Array.unsafe_set weightsi j (weightij +. change);
done
done
(* from the first layer nothing has to be returned *)
end
| [] ->
()
in loop rep input