-module(gleam_synapses@model@net_elems@activation). -compile(no_auto_import). -export([math_exp/1, math_log/1, math_tanh/1, restricted_input/2, restricted_output/2, sigmoid/0, identity/0, tanh/0, leaky_re_lu/0, serialized/1, deserialized/1, json_encoded/1, json_decoder/0, generator/0]). -export_type([activation/0]). -type activation() :: {activation, binary(), fun((float()) -> float()), fun((float()) -> float()), fun((float()) -> float()), {float(), float()}}. -spec math_exp(float()) -> float(). math_exp(A) -> math:exp(A). -spec math_log(float()) -> float(). math_log(A) -> math:log(A). -spec math_tanh(float()) -> float(). math_tanh(A) -> math:tanh(A). -spec restricted_input(activation(), float()) -> float(). restricted_input(Activation, X) -> {Min, Max} = erlang:element(6, Activation), gleam@float:clamp(X, Min, Max). -spec restricted_output(activation(), float()) -> float(). restricted_output(Activation, Y) -> {Min, Max} = erlang:element(6, Activation), gleam@float:clamp( Y, (erlang:element(3, Activation))(Min), (erlang:element(3, Activation))(Max) ). -spec min_abs_float(boolean()) -> float(). min_abs_float(Is_positive) -> X = 1.7976931348623157 * gleam@float:power(10.0, 308.0), case Is_positive of true -> X; false -> 0.0 - X end. -spec sigmoid_f(float()) -> float(). sigmoid_f(X) -> case (1.0 + math:exp(0.0 - X)) of 0.0 -> 0.0; Gleam@denominator -> 1.0 / Gleam@denominator end. -spec sigmoid() -> activation(). sigmoid() -> {activation, <<"sigmoid"/utf8>>, fun sigmoid_f/1, fun(D) -> sigmoid_f(D) * (1.0 - sigmoid_f(D)) end, fun(Y) -> math:log(case (1.0 - Y) of 0.0 -> 0.0; Gleam@denominator -> Y / Gleam@denominator end) end, {-700.0, 20.0}}. -spec identity() -> activation(). identity() -> {activation, <<"identity"/utf8>>, fun(X) -> X end, fun(_) -> 1.0 end, fun(Y) -> Y end, {min_abs_float(false), min_abs_float(true)}}. -spec tanh() -> activation(). tanh() -> {activation, <<"tanh"/utf8>>, fun math:tanh/1, fun(D) -> 1.0 - (math:tanh(D) * math:tanh(D)) end, fun(Y) -> 0.5 * math:log(case (1.0 - Y) of 0.0 -> 0.0; Gleam@denominator -> (1.0 + Y) / Gleam@denominator end) end, {-10.0, 10.0}}. -spec leaky_re_lu() -> activation(). leaky_re_lu() -> {activation, <<"leakyReLU"/utf8>>, fun(X) -> case X < 0.0 of true -> 0.01 * X; false -> X end end, fun(D) -> case D < 0.0 of true -> 0.01; false -> 1.0 end end, fun(Y) -> case Y < 0.0 of true -> Y / 0.01; false -> Y end end, {min_abs_float(false), min_abs_float(true)}}. -spec serialized(activation()) -> binary(). serialized(Activation) -> erlang:element(2, Activation). -spec deserialized(binary()) -> activation(). deserialized(Activation_serialised) -> case Activation_serialised of <<"sigmoid"/utf8>> -> sigmoid(); <<"identity"/utf8>> -> identity(); <<"tanh"/utf8>> -> tanh(); <<"leakyReLU"/utf8>> -> leaky_re_lu() end. -spec json_encoded(binary()) -> gleam_synapses@model@edited_jsone:json_value(). json_encoded(Activation_serialised) -> gleam_synapses@model@edited_jsone:string(Activation_serialised). -spec json_decoder() -> decode:decoder(binary()). json_decoder() -> decode:string(). -spec generator() -> minigen:generator(activation()). generator() -> minigen:always(sigmoid()).