From 23d6877a17b5ef117a921d072e782cdd70256db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Rei=C3=9Fmann?= Date: Tue, 18 Feb 2025 08:41:25 +1100 Subject: [PATCH 1/5] add dim to new reg --- paper/ConstraintViaSBP.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper/ConstraintViaSBP.jl b/paper/ConstraintViaSBP.jl index 37af476..391bf06 100644 --- a/paper/ConstraintViaSBP.jl +++ b/paper/ConstraintViaSBP.jl @@ -142,7 +142,7 @@ function main() #perform the regression by entering epochs, population_size, the feature cols, the target col and the loss function fit!(regressor, epochs, population_size, x_train', y_train; - x_test=x_test', y_test=y_test', + x_test=x_test', y_test=y_test', target_dimension=target_dim, loss_fun="mse", break_condition=break_condition) end_time = (time_ns() - start_time) / 1e9 From d52978d05434ad608a857fc37b5c5b98df93b0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Rei=C3=9Fmann?= Date: Fri, 21 Feb 2025 13:13:35 +1100 Subject: [PATCH 2/5] solve module dependecies --- src/Entities.jl | 8 +-- src/GeneExpressionProgramming.jl | 117 ++++++++++++++++++++++++------- src/Gep.jl | 11 +-- src/RegressionWrapper.jl | 35 ++++----- src/Util.jl | 1 - test/Entity_test.jl | 3 - test/Main_min_example_mo.jl | 2 - test/Spb_core_test.jl | 4 -- test/non_dom_sort_test.jl | 5 -- test/regression_wrapper_test.jl | 3 - test/runtests.jl | 4 ++ test/tensor_ops_test.jl | 2 - 12 files changed, 112 insertions(+), 83 deletions(-) diff --git a/src/Entities.jl b/src/Entities.jl index fc6818f..f6b1251 100644 --- a/src/Entities.jl +++ b/src/Entities.jl @@ -77,12 +77,8 @@ export fitness, set_fitness! export generate_gene, compile_expression!, generate_chromosome, generate_population export genetic_operations!, replicate, gene_inversion!, gene_mutation!, gene_one_point_cross_over!, gene_two_point_cross_over!, gene_fussion! -include("Util.jl") -include("TensorOps.jl") - - -using .GepUtils -using .TensorRegUtils +using ..GepUtils +using ..TensorRegUtils using OrderedCollections using DynamicExpressions diff --git a/src/GeneExpressionProgramming.jl b/src/GeneExpressionProgramming.jl index 8b01a4c..a013ff1 100644 --- a/src/GeneExpressionProgramming.jl +++ b/src/GeneExpressionProgramming.jl @@ -78,18 +78,31 @@ dims = get_constant_dims(constant) - Includes comprehensive utilities for tree manipulation and unit consistency """ +include("Util.jl") +include("TensorOps.jl") include("Entities.jl") -include("Gep.jl") include("Losses.jl") -include("PhyConstants.jl") -include("Sbp.jl") include("Selection.jl") -include("Util.jl") +include("Sbp.jl") +# First export the submodules themselves +export GepUtils, TensorRegUtils, GepEntities, LossFunction, EvoSelection, SBPUtils + +include("Gep.jl") +include("PhyConstants.jl") include("RegressionWrapper.jl") +export PhysicalConstants, GepRegression, RegressionWrapper -# First export the submodules themselves -export GepEntities, LossFunction, PhysicalConstants, - GepUtils, GepRegression, RegressionWrapper, GPSurrogate +# Import core functions for tensor regression +import .TensorRegUtils: + OperationNode, InputSelector, + AdditionNode, SubtractionNode, MultiplicationNode, DivisionNode, PowerNode, + MinNode, MaxNode, InversionNode, + TraceNode, DeterminantNode, SymmetricNode, SkewNode, + VolumetricNode, DeviatricNode, TdotNode, DottNode, + DoubleContractionNode, DeviatoricNode, + ConstantNode, UnaryNode, + compile_to_flux_network, + TENSOR_NODES, TENSOR_NODES_ARITY # Import GEP core functionality import .GepRegression: @@ -192,31 +205,81 @@ import .RegressionWrapper: set_arity!, set_forward_handler!, set_backward_handler!, - update_function! - + update_function!, + create_physical_operations, + create_function_entries, + create_constants_entries, + create_feature_entries +# Export GEP core functionality export runGep, EvaluationStrategy, StandardRegressionStrategy, GenericRegressionStrategy + +# Export structures for the tensor regression +export OperationNode, InputSelector, + AdditionNode, SubtractionNode, MultiplicationNode, DivisionNode, PowerNode, + MinNode, MaxNode, InversionNode, + TraceNode, DeterminantNode, SymmetricNode, SkewNode, + VolumetricNode, DeviatricNode, TdotNode, DottNode, + DoubleContractionNode, DeviatoricNode, + ConstantNode, UnaryNode, + compile_to_flux_network, + TENSOR_NODES, TENSOR_NODES_ARITY + + +# Export core GEP entities and operations +export Chromosome, Toolbox, fitness, set_fitness!, + generate_gene, compile_expression!, generate_chromosome, generate_population, + genetic_operations! + +# Export regression components +export GepRegressor, GepTensorRegressor, fit!, + list_all_functions, list_all_arity, list_all_forward_handlers, + list_all_backward_handlers, list_all_genetic_params, + set_function!, set_arity!, set_forward_handler!, set_backward_handler!, + update_function!, create_physical_operations, create_function_entries, create_constants_entries, + create_feature_entries + +# Export loss functions export get_loss_function -export find_indices_with_sum, compile_djl_datatype, optimize_constants!, minmax_scale, isclose -export save_state, load_state, record_history!, record!, close_recorder! -export HistoryRecorder, OptimizationHistory, get_history_arrays -export train_test_split -export tournament_selection, nsga_selection, dominates_, fast_non_dominated_sort, calculate_fronts, determine_ranks, assign_crowding_distance -export physical_constants, physical_constants_all, get_constant, get_constant_value, get_constant_dims + +# Export selection mechanisms +export tournament_selection, nsga_selection, dominates_, + fast_non_dominated_sort, calculate_fronts, + determine_ranks, assign_crowding_distance + +# Export physical constants functionality +export physical_constants, physical_constants_all, + get_constant, get_constant_value, get_constant_dims + +# Export symbolic computation types export TokenLib, TokenDto, LibEntry, TempComputeTree -export create_lib, create_compute_tree, propagate_necessary_changes!, calculate_vector_dimension!, flush!, flatten_dependents -export correct_genes!, equal_unit_forward, mul_unit_forward, div_unit_forward -export zero_unit_backward, zero_unit_forward, sqr_unit_backward, sqr_unit_forward, mul_unit_backward, div_unit_backward, equal_unit_backward -export get_feature_dims_json, get_target_dim_json, retrieve_coeffs_based_on_similarity -export Chromosome, Toolbox, fitness, set_fitness! -export generate_gene, compile_expression!, generate_chromosome, generate_population -export genetic_operations! -export GepRegressor,GepTensorRegressor, fit! -export list_all_functions, list_all_arity, list_all_forward_handlers -export list_all_backward_handlers, list_all_genetic_params -export set_function!, set_arity!, set_forward_handler!, set_backward_handler! -export update_function! + +# Export symbolic computation utilities +export create_lib, create_compute_tree, + propagate_necessary_changes!, calculate_vector_dimension!, + flush!, flatten_dependents, correct_genes!, + get_feature_dims_json, get_target_dim_json, + retrieve_coeffs_based_on_similarity + +# Export unit handling operations +export equal_unit_forward, mul_unit_forward, div_unit_forward, + zero_unit_backward, zero_unit_forward, + sqr_unit_backward, sqr_unit_forward, + mul_unit_backward, div_unit_backward, equal_unit_backward + +# Export general utilities +export find_indices_with_sum, compile_djl_datatype, + optimize_constants!, minmax_scale, isclose, + save_state, load_state, + train_test_split + +# Export history recording functionality +export HistoryRecorder, OptimizationHistory, + record_history!, record!, close_recorder!, + get_history_arrays + +# Export common libraries export ARITY_LIB_COMMON, FUNCTION_LIB_COMMON diff --git a/src/Gep.jl b/src/Gep.jl index 198fb14..5b8f93d 100644 --- a/src/Gep.jl +++ b/src/Gep.jl @@ -63,15 +63,10 @@ See also: module GepRegression -include("Losses.jl") -include("Util.jl") -include("Selection.jl") - - -using .LossFunction -using .GepUtils -using .EvoSelection +using ..GepUtils using ..GepEntities +using ..LossFunction +using ..EvoSelection using Random diff --git a/src/RegressionWrapper.jl b/src/RegressionWrapper.jl index c682d21..975160a 100644 --- a/src/RegressionWrapper.jl +++ b/src/RegressionWrapper.jl @@ -131,29 +131,20 @@ export list_all_functions, list_all_arity, list_all_forward_handlers, set_function!, set_arity!, set_forward_handler!, set_backward_handler!, update_function!, vec_add, vec_mul -include("Entities.jl") -include("Gep.jl") -include("Losses.jl") -include("PhyConstants.jl") -include("Sbp.jl") -include("Selection.jl") -include("Util.jl") -include("TensorOps.jl") - - -using .GepEntities -using .LossFunction -using .EvoSelection - -using .GepRegression -using .SBPUtils -using .GepUtils -using .TensorRegUtils + +using ..GepEntities +using ..LossFunction +using ..EvoSelection + +using ..GepRegression +using ..SBPUtils +using ..GepUtils +using ..TensorRegUtils using DynamicExpressions using OrderedCollections using LinearAlgebra -const InputSelector = TensorRegUtils.InputSelector + """ FUNCTION_LIB_FORWARD_COMMON::Dict{Symbol,Function} @@ -533,7 +524,7 @@ mutable struct GepRegressor token_dto = nothing end - toolbox = GepRegression.GepEntities.Toolbox(gene_count, head_len, utilized_symbols, gene_connections_, + toolbox = Toolbox(gene_count, head_len, utilized_symbols, gene_connections_, callbacks, nodes, GENE_COMMON_PROBS; preamble_syms=preamble_syms_, number_of_objectives=number_of_objectives, operators_=operators) @@ -645,7 +636,7 @@ mutable struct GepTensorRegressor cur_idx += 1 end - toolbox = GepRegression.GepEntities.Toolbox(gene_count, head_len, utilized_symbols, gene_connections_, + toolbox = Toolbox(gene_count, head_len, utilized_symbols, gene_connections_, callbacks, nodes, GENE_COMMON_PROBS; number_of_objectives=number_of_objectives, operators_=nothing, function_complile=compile_to_flux_network) @@ -688,7 +679,7 @@ function fit!(regressor::GepRegressor, epochs::Int, population_size::Int, x_trai correction_epochs::Int=1, correction_amount::Real=0.05, opt_method_const::Symbol=:cg, target_dimension::Union{Vector{Float16},Nothing}=nothing, - cycles::Int=10, max_iterations::Int=150, n_starts::Int=5, + cycles::Int=10, max_iterations::Int=1000, n_starts::Int=3, break_condition::Union{Function,Nothing}=nothing ) diff --git a/src/Util.jl b/src/Util.jl index 6301672..da5b37b 100644 --- a/src/Util.jl +++ b/src/Util.jl @@ -698,7 +698,6 @@ See also: [`DynamicExpressions.Node`](@ref), [`Optim.optimize`](@ref), [`LineSea set_scalar_constants!(current_node,x, refs) loss(current_node) end - result = Optim.optimize(opt_step, x0, algorithm, optimizer_options) if result.minimum < best_loss diff --git a/test/Entity_test.jl b/test/Entity_test.jl index 5ebc581..cbc84bd 100644 --- a/test/Entity_test.jl +++ b/test/Entity_test.jl @@ -1,6 +1,3 @@ -include("../src/Entities.jl") - -using .GepEntities using DynamicExpressions using Test using OrderedCollections diff --git a/test/Main_min_example_mo.jl b/test/Main_min_example_mo.jl index 960e211..508f28f 100644 --- a/test/Main_min_example_mo.jl +++ b/test/Main_min_example_mo.jl @@ -6,8 +6,6 @@ using Plots using DynamicExpressions using Statistics -const Chromosome = GepEntities.Chromosome - Random.seed!(1) diff --git a/test/Spb_core_test.jl b/test/Spb_core_test.jl index f044909..05c7220 100644 --- a/test/Spb_core_test.jl +++ b/test/Spb_core_test.jl @@ -1,9 +1,5 @@ using Test -include("../src/Sbp.jl") -include("../src/Util.jl") - -using .SBPUtils using Random using OrderedCollections Random.seed!(1) diff --git a/test/non_dom_sort_test.jl b/test/non_dom_sort_test.jl index 9bfbba8..64556b3 100644 --- a/test/non_dom_sort_test.jl +++ b/test/non_dom_sort_test.jl @@ -1,10 +1,5 @@ using Test -include("../src/Selection.jl") - -using .EvoSelection - - function create_population(data) return data end diff --git a/test/regression_wrapper_test.jl b/test/regression_wrapper_test.jl index a3f4ebf..a936500 100644 --- a/test/regression_wrapper_test.jl +++ b/test/regression_wrapper_test.jl @@ -1,6 +1,3 @@ -include("../src/RegressionWrapper.jl") - -using .RegressionWrapper using Test using OrderedCollections using DynamicExpressions diff --git a/test/runtests.jl b/test/runtests.jl index ab370c9..935ee5a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,3 +1,7 @@ +include("../src/GeneExpressionProgramming.jl") + +using .GeneExpressionProgramming + include("Entity_test.jl") include("Spb_core_test.jl") include("non_dom_sort_test.jl") diff --git a/test/tensor_ops_test.jl b/test/tensor_ops_test.jl index 5c48ab0..0dea69a 100644 --- a/test/tensor_ops_test.jl +++ b/test/tensor_ops_test.jl @@ -1,7 +1,5 @@ -include("../src/TensorOps.jl") using BenchmarkTools using Test -using .TensorRegUtils using Tensors using OrderedCollections using Flux From 741f126443e68edf3e93a6325ab5dfa200d9cfda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Rei=C3=9Fmann?= Date: Fri, 21 Feb 2025 14:46:40 +1100 Subject: [PATCH 3/5] restruct gene --- src/Entities.jl | 4 ++-- src/GeneExpressionProgramming.jl | 4 ++-- src/RegressionWrapper.jl | 12 ++++++------ src/TensorOps.jl | 10 ++++++++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Entities.jl b/src/Entities.jl index f6b1251..39eb21f 100644 --- a/src/Entities.jl +++ b/src/Entities.jl @@ -439,10 +439,10 @@ Vector{Int8} representing gene @inline function generate_gene(headsyms::Vector{Int8}, tailsyms::Vector{Int8}, headlen::Int; unarys::Vector{Int8}=[], unary_prob::Real=0.2, tensor_prob::Real=0.2) if !isempty(unarys) && rand() < unary_prob - heads = vcat(headsyms, tailsyms) + heads = vcat(headsyms, rand(tailsyms,2)) push!(heads, rand(unarys)) else - heads = headsyms + heads = vcat(headsyms, rand(tailsyms,2)) end head = rand(heads, headlen) diff --git a/src/GeneExpressionProgramming.jl b/src/GeneExpressionProgramming.jl index a013ff1..b38c9c3 100644 --- a/src/GeneExpressionProgramming.jl +++ b/src/GeneExpressionProgramming.jl @@ -94,7 +94,7 @@ export PhysicalConstants, GepRegression, RegressionWrapper # Import core functions for tensor regression import .TensorRegUtils: - OperationNode, InputSelector, + InputSelector, AdditionNode, SubtractionNode, MultiplicationNode, DivisionNode, PowerNode, MinNode, MaxNode, InversionNode, TraceNode, DeterminantNode, SymmetricNode, SkewNode, @@ -216,7 +216,7 @@ import .RegressionWrapper: export runGep, EvaluationStrategy, StandardRegressionStrategy, GenericRegressionStrategy # Export structures for the tensor regression -export OperationNode, InputSelector, +export InputSelector, AdditionNode, SubtractionNode, MultiplicationNode, DivisionNode, PowerNode, MinNode, MaxNode, InversionNode, TraceNode, DeterminantNode, SymmetricNode, SkewNode, diff --git a/src/RegressionWrapper.jl b/src/RegressionWrapper.jl index 975160a..1a4954d 100644 --- a/src/RegressionWrapper.jl +++ b/src/RegressionWrapper.jl @@ -254,16 +254,16 @@ Dictionary containing default probabilities and parameters for genetic algorithm These values can be adjusted to fine-tune the genetic algorithm's behavior. """ const GENE_COMMON_PROBS = Dict{String,AbstractFloat}( - "one_point_cross_over_prob" => 0.5, - "two_point_cross_over_prob" => 0.3, + "one_point_cross_over_prob" => 0.3, + "two_point_cross_over_prob" => 0.2, "mutation_prob" => 1.0, - "mutation_rate" => 0.1, + "mutation_rate" => 0.05, "dominant_fusion_prob" => 0.1, - "dominant_fusion_rate" => 0.2, + "dominant_fusion_rate" => 0.1, "rezessiv_fusion_prob" => 0.1, - "rezessiv_fusion_rate" => 0.2, + "rezessiv_fusion_rate" => 0.1, "fusion_prob" => 0.1, - "fusion_rate" => 0.2, + "fusion_rate" => 0.1, "inversion_prob" => 0.1, "reverse_insertion" => 0.1, "reverse_insertion_tail" => 0.1, diff --git a/src/TensorOps.jl b/src/TensorOps.jl index acbc658..c6ff27e 100644 --- a/src/TensorOps.jl +++ b/src/TensorOps.jl @@ -2,6 +2,8 @@ module TensorRegUtils using Flux, LinearAlgebra, OrderedCollections, ChainRulesCore, Tensors, PrecompileTools + + # Abstract base type with parametric types for improved type stability abstract type AbstractOperationNode{T} end @@ -295,6 +297,10 @@ function compile_to_flux_network(rek_string::Vector, arity_map::OrderedDict, cal return Chain(pop!(stack)) end +function string() + +end + # Constant mappings const TENSOR_NODES = Dict{Symbol,Type}( :+ => AdditionNode, @@ -326,7 +332,7 @@ const TENSOR_NODES_ARITY = Dict{Symbol,Int8}( ) # Exports -export OperationNode, InputSelector +export InputSelector export AdditionNode, SubtractionNode, MultiplicationNode, DivisionNode, PowerNode export MinNode, MaxNode, InversionNode export TraceNode, DeterminantNode, SymmetricNode, SkewNode @@ -384,4 +390,4 @@ export TENSOR_NODES, TENSOR_NODES_ARITY end end -end +end \ No newline at end of file From e78b6f957035af9ae0ec13c3e66dda1941069a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Rei=C3=9Fmann?= Date: Fri, 21 Feb 2025 17:22:48 +1100 Subject: [PATCH 4/5] add split --- src/Entities.jl | 20 +++++++++++++++---- src/GeneExpressionProgramming.jl | 5 +++-- src/Gep.jl | 28 +++++++++++++++----------- src/RegressionWrapper.jl | 34 ++++++++++++++++++++++++-------- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/src/Entities.jl b/src/Entities.jl index 39eb21f..0bfe060 100644 --- a/src/Entities.jl +++ b/src/Entities.jl @@ -75,7 +75,7 @@ module GepEntities export Chromosome, Toolbox, EvaluationStrategy, StandardRegressionStrategy, GenericRegressionStrategy export fitness, set_fitness! export generate_gene, compile_expression!, generate_chromosome, generate_population -export genetic_operations!, replicate, gene_inversion!, gene_mutation!, gene_one_point_cross_over!, gene_two_point_cross_over!, gene_fussion! +export genetic_operations!, replicate, gene_inversion!, gene_mutation!, gene_one_point_cross_over!, gene_two_point_cross_over!, gene_fussion!, split_karva using ..GepUtils using ..TensorRegUtils @@ -397,8 +397,7 @@ Vector{Int8} representing the K-expression of the chromosome ``` """ - -@inline function _karva_raw(chromosome::Chromosome) +@inline function _karva_raw(chromosome::Chromosome; split::Bool=false) gene_len = chromosome.toolbox.head_len * 2 + 1 gene_count = chromosome.toolbox.gene_count @@ -416,9 +415,22 @@ Vector{Int8} representing the K-expression of the chromosome rolled_indices[idx+1] = @view genes[i:i+first(indices)-1] end - return vcat(rolled_indices...) + !split && return vcat(rolled_indices...) + return rolled_indices end +@inline function split_karva(chromosome::Chromosome, coeffs::Int=2) + raw = _karva_raw(chromosome; split=true) + connectors = popfirst!(raw)[coeffs:end] + gene_count_per_factor = div(chromosome.toolbox.gene_count,coeffs) + retval = [] + for _ in 1:coeffs + temp_cons = splice!(connectors, 1:gene_count_per_factor-1) + temp_genes = reduce(vcat, splice!(raw,1:gene_count_per_factor)) + push!(retval,vcat([temp_cons, temp_genes]...)) + end + return retval +end """ generate_gene(headsyms::Vector{Int8}, tailsyms::Vector{Int8}, headlen::Int; diff --git a/src/GeneExpressionProgramming.jl b/src/GeneExpressionProgramming.jl index b38c9c3..6ab9e7b 100644 --- a/src/GeneExpressionProgramming.jl +++ b/src/GeneExpressionProgramming.jl @@ -189,7 +189,8 @@ import .GepEntities: compile_expression!, generate_chromosome, generate_population, - genetic_operations! + genetic_operations!, + split_karva # Import regression wrapper functionality import .RegressionWrapper: @@ -230,7 +231,7 @@ export InputSelector, # Export core GEP entities and operations export Chromosome, Toolbox, fitness, set_fitness!, generate_gene, compile_expression!, generate_chromosome, generate_population, - genetic_operations! + genetic_operations!, split_karva # Export regression components export GepRegressor, GepTensorRegressor, fit!, diff --git a/src/Gep.jl b/src/Gep.jl index 5b8f93d..52c1a9d 100644 --- a/src/Gep.jl +++ b/src/Gep.jl @@ -118,7 +118,7 @@ Returns the computed fitness value (loss) or crash_value if computation fails y_pred = elem.compiled_function(evalArgs.x_data, evalArgs.operators) return (evalArgs.loss_function(evalArgs.y_data, y_pred),) else - return (elem.fitness,) + return elem.fitness end catch e return (evalArgs.crash_value,) @@ -274,7 +274,10 @@ The evolution process stops when either: correction_epochs::Int=1, correction_amount::Real=0.6, tourni_size::Int=3, - optimization_epochs::Int=500) + optimization_epochs::Int=500, + file_logger_callback::Union{Function, Nothing}=nothing, + save_state_callback::Union{Function, Nothing}=nothing, + load_state_callback::Union{Function, Nothing}=nothing) recorder = HistoryRecorder(epochs, Tuple) mating_ = toolbox.gep_probs["mating_size"] @@ -284,11 +287,12 @@ The evolution process stops when either: fit_cache = Dict{Vector{Int8},Tuple}() cache_lock = SpinLock() - population = generate_population(population_size, toolbox) + population, start_epoch = isnothing(load_state_callback) ? (generate_population(population_size, toolbox), 1) : load_state_callback() next_gen = Vector{eltype(population)}(undef, mating_size) progBar = Progress(epochs; showspeed=true, desc="Training: ") prev_best = (typemax(Float64),) - for epoch in 1:epochs + + for epoch in start_epoch:epochs same = Atomic{Int}(0) perform_correction_callback!(population, epoch, correction_epochs, correction_amount, correction_callback) @@ -332,18 +336,20 @@ The evolution process stops when either: update_surrogate!(evalStrategy) - if !isnothing(evalStrategy.break_condition) && evalStrategy.break_condition(population, epoch) break end - if epoch < epochs - if length(fits_representation[1]) == 1 - selectedMembers = tournament_selection(fits_representation, mating_size, tourni_size) - else - selectedMembers = nsga_selection(fits_representation) - end + if length(fits_representation[1]) == 1 + selectedMembers = tournament_selection(fits_representation, mating_size, tourni_size) + else + selectedMembers = nsga_selection(fits_representation) + end + + !isnothing(file_logger_callback) && file_logger_callback(population, epoch, selectedMembers) + !isnothing(save_state_callback) && save_state_callback(population, epoch) + if epoch < epochs parents = population[selectedMembers.indices] perform_step!(population, parents, next_gen, toolbox, mating_size) end diff --git a/src/RegressionWrapper.jl b/src/RegressionWrapper.jl index 1a4954d..612b44f 100644 --- a/src/RegressionWrapper.jl +++ b/src/RegressionWrapper.jl @@ -583,7 +583,7 @@ mutable struct GepTensorRegressor fitness_history_::Any - function GepTensorRegressor(scalar_feature_amount::Int; + function GepTensorRegressor(scalar_feature_amount::Int; higher_dim_feature_amount::Int=0, entered_non_terminals::Vector{Symbol}=[:+, :-, :*], entered_terminal_nums::Vector{<:AbstractFloat}=Float64[], @@ -631,7 +631,7 @@ mutable struct GepTensorRegressor callbacks[cur_idx] = TENSOR_NODES[elem] utilized_symbols[cur_idx] = TENSOR_NODES_ARITY[elem] if elem in gene_connections - push!(gene_connections_,cur_idx) + push!(gene_connections_, cur_idx) end cur_idx += 1 end @@ -680,7 +680,10 @@ function fit!(regressor::GepRegressor, epochs::Int, population_size::Int, x_trai opt_method_const::Symbol=:cg, target_dimension::Union{Vector{Float16},Nothing}=nothing, cycles::Int=10, max_iterations::Int=1000, n_starts::Int=3, - break_condition::Union{Function,Nothing}=nothing + break_condition::Union{Function,Nothing}=nothing, + file_logger_callback::Union{Function,Nothing}=nothing, + save_state_callback::Union{Function,Nothing}=nothing, + load_state_callback::Union{Function,Nothing}=nothing ) correction_callback = if !isnothing(target_dimension) @@ -732,7 +735,10 @@ function fit!(regressor::GepRegressor, epochs::Int, population_size::Int, x_trai correction_epochs=correction_epochs, correction_amount=correction_amount, tourni_size=max(Int(ceil(population_size * 0.03)), 3), - optimization_epochs=optimization_epochs + optimization_epochs=optimization_epochs, + file_logger_callback=file_logger_callback, + save_state_callback=save_state_callback, + load_state_callback=load_state_callback ) regressor.best_models_ = best @@ -748,7 +754,10 @@ function fit!(regressor::GepRegressor, epochs::Int, population_size::Int, loss_f opt_method_const::Symbol=:nd, target_dimension::Union{Vector{Float16},Nothing}=nothing, cycles::Int=10, max_iterations::Int=150, n_starts::Int=5, - break_condition::Union{Function,Nothing}=nothing + break_condition::Union{Function,Nothing}=nothing, + file_logger_callback::Union{Function,Nothing}=nothing, + save_state_callback::Union{Function,Nothing}=nothing, + load_state_callback::Union{Function,Nothing}=nothing ) correction_callback = if !isnothing(target_dimension) @@ -793,7 +802,10 @@ function fit!(regressor::GepRegressor, epochs::Int, population_size::Int, loss_f correction_epochs=correction_epochs, correction_amount=correction_amount, tourni_size=max(Int(ceil(population_size * 0.03)), 3), - optimization_epochs=optimization_epochs + optimization_epochs=optimization_epochs, + file_logger_callback=file_logger_callback, + save_state_callback=save_state_callback, + load_state_callback=load_state_callback ) regressor.best_models_ = best @@ -802,7 +814,10 @@ end function fit!(regressor::GepTensorRegressor, epochs::Int, population_size::Int, loss_function::Function; hof::Int=3, - break_condition::Union{Function,Nothing}=nothing + break_condition::Union{Function,Nothing}=nothing, + file_logger_callback::Union{Function, Nothing}=nothing, + save_state_callback::Union{Function, Nothing}=nothing, + load_state_callback::Union{Function, Nothing}=nothing ) evalStrat = GenericRegressionStrategy( @@ -818,7 +833,10 @@ function fit!(regressor::GepTensorRegressor, epochs::Int, population_size::Int, regressor.toolbox_, evalStrat; hof=hof, - tourni_size=max(Int(ceil(population_size * 0.003)), 3) + tourni_size=max(Int(ceil(population_size * 0.003)), 3), + file_logger_callback=file_logger_callback, + save_state_callback=save_state_callback, + load_state_callback=load_state_callback ) regressor.best_models_ = best From e740c665e75ededa52f0e1420159373c542610e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Rei=C3=9Fmann?= Date: Fri, 21 Feb 2025 18:39:36 +1100 Subject: [PATCH 5/5] add cite --- README.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ab37d07..d6b6586 100644 --- a/README.md +++ b/README.md @@ -150,17 +150,35 @@ fit!(regressor, epochs, population_size, loss_new) # Supported `Engines' for Symbolic Evaluation - DynamicExpressions.jl -- Flux.jl --> in development +- Flux.jl --> should be utilized when performing tensor regression # References - [1] Ferreira, C. (2001). Gene Expression Programming: a New Adaptive Algorithm for Solving Problems. Complex Systems, 13. -- [2] Reissmann, M., Fang, Y., Ooi, A., & Sandberg, R. (2024). Constraining genetic symbolic regression via semantic backpropagation. arXiv. https://arxiv.org/abs/2409.07369 +- [2] Reissmann, M., Fang, Y., Ooi, A. S. H., & Sandberg, R. D. (2025). Constraining genetic symbolic regression via semantic backpropagation. Genetic Programming and Evolvable Machines, 26(1), 12 # Acknowledgement - The Coefficient optimization is inspired by [https://github.com/MilesCranmer/SymbolicRegression.jl](https://github.com/MilesCranmer/SymbolicRegression.jl/blob/master/src/ConstantOptimization.jl) - We employ the insane fast [DynamicExpressions.jl](https://github.com/SymbolicML/DynamicExpressions.jl) for evaluating our expressions + +# How to cite +Feel free to utilize it for your research, it would be nice __citing us__! Our [paper](https://doi.org/10.1007/s10710-025-09510-z). +``` +@article{Reissmann2025, + author = {Maximilian Reissmann and Yuan Fang and Andrew S. H. Ooi and Richard D. Sandberg}, + title = {Constraining Genetic Symbolic Regression via Semantic Backpropagation}, + journal = {Genetic Programming and Evolvable Machines}, + year = {2025}, + volume = {26}, + number = {1}, + pages = {12}, + doi = {10.1007/s10710-025-09510-z}, + url = {https://doi.org/10.1007/s10710-025-09510-z} +} + +``` + # Todo - [ ] Documentation - [x] Naming conventions!