The cost function should be a field of Individual to allow using arbitrary custom implementations.
We should then probably implement something like a CostFunction struct similar to Activation that holds a name, the actual function and its derivative since we will need the first for (de-)serialization and the other two in the actual gradient descent algorithm.
To simplify deserialization, we can annotate that new Individual cost function field with something like #[serde(default = "get_quadratic_cost_function")] and have get_quadratic_cost_function return a default CostFunction struct representing the quadratic cost function, whenever the (e.g.) JSON input is missing a cost_function field.
Right now the
backprop
algorithm uses the hard-coded (derivative of the) quadratic cost function to calculate the delta values:https://github.com/mfajnberg/tensorevo/blob/b7119f3c89b17d45ae3c3a49022f0f93a555ba97/src/individual.rs#L122-L125
Also, the validation error is calculated via the hard-coded quadratic cost function:
https://github.com/mfajnberg/tensorevo/blob/b7119f3c89b17d45ae3c3a49022f0f93a555ba97/src/individual.rs#L179
The cost function should be a field of
Individual
to allow using arbitrary custom implementations.We should then probably implement something like a
CostFunction
struct similar toActivation
that holds a name, the actual function and its derivative since we will need the first for (de-)serialization and the other two in the actual gradient descent algorithm.To simplify deserialization, we can annotate that new
Individual
cost function field with something like#[serde(default = "get_quadratic_cost_function")]
and haveget_quadratic_cost_function
return a defaultCostFunction
struct representing the quadratic cost function, whenever the (e.g.) JSON input is missing acost_function
field.