-module(gleam_synapses@model@net_elems@network). -compile(no_auto_import). -export([init/3, output/2, errors/4, fit/4, to_json/1, of_json/1, generator/1]). -spec lazy_realization( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())) ) -> gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())). lazy_realization(Network) -> serialized(Network), Network. -spec init( gleam_zlists@interop:z_list(integer()), fun((integer()) -> gleam_synapses@model@net_elems@activation:activation()), fun((integer()) -> float()) ) -> gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())). init(Layer_sizes, Activation_f, Weight_init_f) -> {ok, Tl} = gleam_zlists:tail(Layer_sizes), lazy_realization( gleam_zlists:map( gleam_zlists:with_index(gleam_zlists:zip(Layer_sizes, Tl)), fun(T) -> {{Lr_sz, Next_lr_sz}, Index} = T, gleam_synapses@model@net_elems@layer:init( Lr_sz, Next_lr_sz, Activation_f(Index), fun() -> fun() -> Weight_init_f(Index) end end ) end ) ). -spec output( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())), gleam_zlists@interop:z_list(float()) ) -> gleam_zlists@interop:z_list(float()). output(Network, Input_val) -> gleam_zlists:reduce( Network, Input_val, fun(X, Acc) -> gleam_synapses@model@net_elems@layer:output(X, Acc) end ). -spec fed_forward_acc_f( gleam_zlists@interop:z_list({gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())}), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron()) ) -> gleam_zlists@interop:z_list({gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())}). fed_forward_acc_f(Already_fed, Next_layer) -> {ok, {Errors_val, Layer_val}} = gleam_zlists:head(Already_fed), Next_input = gleam_synapses@model@net_elems@layer:output( Layer_val, Errors_val ), gleam_zlists:cons(Already_fed, {Next_input, Next_layer}). -spec fed_forward( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())), gleam_zlists@interop:z_list(float()) ) -> gleam_zlists@interop:z_list({gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())}). fed_forward(Network, Input_val) -> {ok, {Net_hd, Net_tl}} = gleam_zlists:uncons(Network), Init_feed = gleam_zlists:singleton({Input_val, Net_hd}), gleam_zlists:reduce( Net_tl, Init_feed, fun(X, Acc) -> fed_forward_acc_f(Acc, X) end ). -spec back_propagated_acc_f( float(), {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron()))}, {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())} ) -> {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron()))}. back_propagated_acc_f( Learning_rate, Errors_with_already_propagated, Input_with_layer ) -> {Errors_val, Already_propagated} = Errors_with_already_propagated, {Last_input, Last_layer} = Input_with_layer, Last_output_with_errors = gleam_zlists:zip( gleam_synapses@model@net_elems@layer:output(Last_layer, Last_input), Errors_val ), {Next_errors, Propagated_layer} = gleam_synapses@model@net_elems@layer:back_propagated( Last_layer, Learning_rate, Last_input, Last_output_with_errors ), Next_already_propagated = gleam_zlists:cons( Already_propagated, Propagated_layer ), {Next_errors, Next_already_propagated}. -spec back_propagated( float(), gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list({gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())}) ) -> {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron()))}. back_propagated(Learning_rate, Expected_output, Reversed_inputs_with_layers) -> {ok, {{Last_input, Last_layer}, Reversed_inputs_with_layers_tl}} = gleam_zlists:uncons( Reversed_inputs_with_layers ), Output_val = gleam_synapses@model@net_elems@layer:output( Last_layer, Last_input ), Errors_val = gleam_zlists:map( gleam_zlists:zip(Output_val, Expected_output), fun(T) -> {A, B} = T, A - B end ), Output_with_errors = gleam_zlists:zip(Output_val, Errors_val), {Init_errors, First_propagated} = gleam_synapses@model@net_elems@layer:back_propagated( Last_layer, Learning_rate, Last_input, Output_with_errors ), Init_acc = {Init_errors, gleam_zlists:singleton(First_propagated)}, gleam_zlists:reduce( Reversed_inputs_with_layers_tl, Init_acc, fun(X, Acc) -> back_propagated_acc_f(Learning_rate, Acc, X) end ). -spec errors_with_fit_net( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())), float(), gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(float()) ) -> {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron()))}. errors_with_fit_net(Network, Learning_rate, Input_val, Expected_output) -> back_propagated( Learning_rate, Expected_output, fed_forward(Network, Input_val) ). -spec errors( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())), float(), gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(float()) ) -> gleam_zlists@interop:z_list(float()). errors(Network, Learning_rate, Input_val, Expected_output) -> {ok, Last_layer} = gleam_zlists:head(gleam_zlists:reverse(Network)), Restricted_output = gleam_zlists:map( gleam_zlists:zip(Last_layer, Expected_output), fun(T) -> {A, B} = T, gleam_synapses@model@net_elems@activation:restricted_output( erlang:element(2, A), B ) end ), gleam@pair:first( errors_with_fit_net( Network, Learning_rate, Input_val, Restricted_output ) ). -spec fit( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())), float(), gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(float()) ) -> gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())). fit(Network, Learning_rate, Input_val, Expected_output) -> {ok, Last_layer} = gleam_zlists:head(gleam_zlists:reverse(Network)), Restricted_output = gleam_zlists:map( gleam_zlists:zip(Last_layer, Expected_output), fun(T) -> {A, B} = T, gleam_synapses@model@net_elems@activation:restricted_output( erlang:element(2, A), B ) end ), lazy_realization( gleam@pair:second( errors_with_fit_net( Network, Learning_rate, Input_val, Restricted_output ) ) ). -spec serialized( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())) ) -> list(list(gleam_synapses@model@net_elems@neuron:neuron_serialized())). serialized(Network) -> gleam_zlists:to_list( gleam_zlists:map( Network, fun gleam_synapses@model@net_elems@layer:serialized/1 ) ). -spec deserialized( list(list(gleam_synapses@model@net_elems@neuron:neuron_serialized())) ) -> gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())). deserialized(Network_serialized) -> gleam_zlists:map( gleam_zlists:of_list(Network_serialized), fun gleam_synapses@model@net_elems@layer:deserialized/1 ). -spec json_encoded( list(list(gleam_synapses@model@net_elems@neuron:neuron_serialized())) ) -> gleam_synapses@model@edited_jsone:json_value(). json_encoded(Network_serialized) -> gleam_synapses@model@edited_jsone:array( Network_serialized, fun gleam_synapses@model@net_elems@layer:json_encoded/1 ). -spec json_decoder() -> decode:decoder(list(list(gleam_synapses@model@net_elems@neuron:neuron_serialized()))). json_decoder() -> decode:list(gleam_synapses@model@net_elems@layer:json_decoder()). -spec to_json( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())) ) -> binary(). to_json(Network) -> {ok, Dyn} = gleam_synapses@model@edited_jsone:encode( json_encoded(serialized(Network)) ), {ok, Res} = decode:decode_dynamic(Dyn, decode:string()), Res. -spec of_json(binary()) -> gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron())). of_json(S) -> {ok, Dyn} = gleam_synapses@model@edited_jsone:decode(S), {ok, Res} = decode:decode_dynamic(Dyn, json_decoder()), lazy_realization(deserialized(Res)). -spec generator(gleam_zlists@interop:z_list(integer())) -> minigen:generator(gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron:neuron()))). generator(Layer_sizes) -> {ok, Tl} = gleam_zlists:tail(Layer_sizes), minigen:map( minigen:map( gleam_zlists:reduce( gleam_zlists:zip(Layer_sizes, Tl), minigen:always(gleam_zlists:new()), fun(T, Acc_gen) -> {Lr_sz, Next_lr_sz} = T, minigen:then( Acc_gen, fun(Acc_zls) -> minigen:map( gleam_synapses@model@net_elems@layer:generator( Lr_sz, Next_lr_sz ), fun(Layer) -> gleam_zlists:cons(Acc_zls, Layer) end ) end ) end ), fun gleam_zlists:reverse/1 ), fun lazy_realization/1 ).