-module(gleam_synapses@model@net_elems@network@network). -compile(no_auto_import). -export([init/3, output/3, errors/4, fit/5, generator/1]). -spec init( gleam_zlists@interop:z_list(integer()), fun((integer()) -> gleam_synapses@model@net_elems@activation@activation:activation()), fun((integer()) -> float()) ) -> gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron())). init(Layer_sizes, Activation_f, Weight_init_f) -> {ok, Tl@1} = case gleam_zlists:tail(Layer_sizes) of {ok, Tl} -> {ok, Tl}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"gleam_synapses/model/net_elems/network/network"/utf8>>, function => <<"init"/utf8>>, line => 15}) end, _pipe = gleam_zlists:zip(Layer_sizes, Tl@1), _pipe@1 = gleam_zlists:with_index(_pipe), gleam_zlists:map( _pipe@1, fun(T) -> {{Lr_sz, Next_lr_sz}, Index} = T, gleam_synapses@model@net_elems@layer@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:neuron())), gleam_zlists@interop:z_list(float()), boolean() ) -> gleam_zlists@interop:z_list(float()). output(Network, Input_val, In_parallel) -> gleam_zlists:reduce( Network, Input_val, fun(X, Acc) -> gleam_synapses@model@net_elems@layer@layer:output( X, Acc, In_parallel ) 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:neuron())}), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron()), boolean() ) -> gleam_zlists@interop:z_list({gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron())}). fed_forward_acc_f(Already_fed, Next_layer, In_parallel) -> {ok, {Errors_val@1, Layer_val@1}} = case gleam_zlists:head(Already_fed) of {ok, {Errors_val, Layer_val}} -> {ok, {Errors_val, Layer_val}}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"gleam_synapses/model/net_elems/network/network"/utf8>>, function => <<"fed_forward_acc_f"/utf8>>, line => 46}) end, Next_input = gleam_synapses@model@net_elems@layer@layer:output( Layer_val@1, Errors_val@1, In_parallel ), 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:neuron())), gleam_zlists@interop:z_list(float()), boolean() ) -> gleam_zlists@interop:z_list({gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron())}). fed_forward(Network, Input_val, In_parallel) -> {ok, {Net_hd@1, Net_tl@1}} = case gleam_zlists:uncons(Network) of {ok, {Net_hd, Net_tl}} -> {ok, {Net_hd, Net_tl}}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"gleam_synapses/model/net_elems/network/network"/utf8>>, function => <<"fed_forward"/utf8>>, line => 56}) end, Init_feed = begin _pipe = {Input_val, Net_hd@1}, gleam_zlists:singleton(_pipe) end, gleam_zlists:reduce( Net_tl@1, Init_feed, fun(X, Acc) -> fed_forward_acc_f(Acc, X, In_parallel) 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:neuron()))}, {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron())}, boolean() ) -> {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron()))}. back_propagated_acc_f( Learning_rate, Errors_with_already_propagated, Input_with_layer, In_parallel ) -> {Errors_val, Already_propagated} = Errors_with_already_propagated, {Last_input, Last_layer} = Input_with_layer, Last_output_with_errors = begin _pipe = gleam_synapses@model@net_elems@layer@layer:output( Last_layer, Last_input, In_parallel ), gleam_zlists:zip(_pipe, Errors_val) end, {Next_errors, Propagated_layer} = gleam_synapses@model@net_elems@layer@layer:back_propagated( Last_layer, Learning_rate, Last_input, Last_output_with_errors, In_parallel ), 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:neuron())}), boolean() ) -> {gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron()))}. back_propagated( Learning_rate, Expected_output, Reversed_inputs_with_layers, In_parallel ) -> {ok, {{Last_input@1, Last_layer@1}, Reversed_inputs_with_layers_tl@1}} = case gleam_zlists:uncons( Reversed_inputs_with_layers ) of {ok, {{Last_input, Last_layer}, Reversed_inputs_with_layers_tl}} -> {ok, {{Last_input, Last_layer}, Reversed_inputs_with_layers_tl}}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"gleam_synapses/model/net_elems/network/network"/utf8>>, function => <<"back_propagated"/utf8>>, line => 96}) end, Output_val = gleam_synapses@model@net_elems@layer@layer:output( Last_layer@1, Last_input@1, In_parallel ), Errors_val = begin _pipe = gleam_zlists:zip(Output_val, Expected_output), gleam_zlists:map( _pipe, fun(T) -> {A, B} = T, A - B end ) end, Output_with_errors = gleam_zlists:zip(Output_val, Errors_val), {Init_errors, First_propagated} = gleam_synapses@model@net_elems@layer@layer:back_propagated( Last_layer@1, Learning_rate, Last_input@1, Output_with_errors, In_parallel ), Init_acc = {Init_errors, gleam_zlists:singleton(First_propagated)}, gleam_zlists:reduce( Reversed_inputs_with_layers_tl@1, Init_acc, fun(X, Acc) -> back_propagated_acc_f(Learning_rate, Acc, X, In_parallel) end ). -spec errors( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron())), gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(float()), boolean() ) -> gleam_zlists@interop:z_list(float()). errors(Network, Input_val, Expected_output, In_parallel) -> _pipe = Network, _pipe@1 = fed_forward(_pipe, Input_val, In_parallel), _pipe@2 = back_propagated(0.0, Expected_output, _pipe@1, In_parallel), gleam@pair:first(_pipe@2). -spec fit( gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron())), float(), gleam_zlists@interop:z_list(float()), gleam_zlists@interop:z_list(float()), boolean() ) -> gleam_zlists@interop:z_list(gleam_zlists@interop:z_list(gleam_synapses@model@net_elems@neuron@neuron:neuron())). fit(Network, Learning_rate, Input_val, Expected_output, In_parallel) -> _pipe = Network, _pipe@1 = fed_forward(_pipe, Input_val, In_parallel), _pipe@2 = back_propagated( Learning_rate, Expected_output, _pipe@1, In_parallel ), gleam@pair:second(_pipe@2). -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:neuron()))). generator(Layer_sizes) -> {ok, Tl@1} = case gleam_zlists:tail(Layer_sizes) of {ok, Tl} -> {ok, Tl}; _try -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _try, module => <<"gleam_synapses/model/net_elems/network/network"/utf8>>, function => <<"generator"/utf8>>, line => 148}) end, _pipe = gleam_zlists:zip(Layer_sizes, Tl@1), _pipe@2 = gleam_zlists:reduce( _pipe, minigen:always(gleam_zlists:new()), fun(T, Acc_gen) -> {Lr_sz, Next_lr_sz} = T, minigen:then( Acc_gen, fun(Acc_zls) -> _pipe@1 = gleam_synapses@model@net_elems@layer@layer:generator( Lr_sz, Next_lr_sz ), minigen:map( _pipe@1, fun(Layer) -> gleam_zlists:cons(Acc_zls, Layer) end ) end ) end ), minigen:map(_pipe@2, fun gleam_zlists:reverse/1).