PySR / paralleleureqa.jl
MilesCranmer's picture
Optimize hall of fame constants with LBFGS
cedbbde
raw
history blame
3.73 kB
include("eureqa.jl")
import Optim
const nthreads = Threads.nthreads()
# List of the best members seen all time
mutable struct HallOfFame
members::Array{PopMember, 1}
exists::Array{Bool, 1} #Whether it has been set
# Arranged by complexity - store one at each.
HallOfFame() = new([PopMember(Node(1f0), 1f9) for i=1:actualMaxsize], [false for i=1:actualMaxsize])
end
function fullRun(niterations::Integer;
npop::Integer=300,
annealing::Bool=true,
ncyclesperiteration::Integer=3000,
fractionReplaced::Float32=0.1f0,
verbosity::Integer=0,
topn::Int32=10
)
debug(verbosity, "Lets try to learn (x2^2 + cos(x3)) using regularized evolution from scratch")
debug(verbosity, "Running with $nthreads threads")
# Generate random initial populations
allPops = [Population(npop, 3) for j=1:nthreads]
bestSubPops = [Population(1) for j=1:nthreads]
# Repeat this many evolutions; we collect and migrate the best
# each time.
hallOfFame = HallOfFame()
for k=1:niterations
# Spawn threads to run indepdent evolutions, then gather them
@inbounds Threads.@threads for i=1:nthreads
allPops[i] = run(allPops[i], ncyclesperiteration, annealing, verbosity=verbosity)
bestSubPops[i] = bestSubPop(allPops[i], topn=topn)
for j=1:bestSubPops[i].n
bestSubPops[i].members[j] = optimizeConstants(bestSubPops[i].members[j])
end
end
# Get best 10 models from each evolution. Copy because we re-assign later.
# bestPops = deepcopy(Population([member for pop in allPops for member in bestSubPop(pop).members]))
bestPops = deepcopy(Population([member for pop in bestSubPops for member in pop.members]))
#Update hall of fame
for member in bestPops.members
size = countNodes(member.tree)
if member.score < hallOfFame.members[size].score
hallOfFame.members[size] = deepcopy(member)
#hallOfFame.members[size] = optimizeConstants(hallOfFame.members[size])
hallOfFame.exists[size] = true
end
end
dominating = PopMember[]
debug(verbosity, "Hall of Fame:")
debug(verbosity, "-----------------------------------------")
debug(verbosity, "Complexity \t MSE \t Equation")
for size=1:maxsize
if hallOfFame.exists[size]
member = hallOfFame.members[size]
numberSmallerAndBetter = sum([member.score > hallOfFame.members[i].score for i=1:(size-1)])
betterThanAllSmaller = (numberSmallerAndBetter == 0)
if betterThanAllSmaller
debug(verbosity, "$size \t $(member.score-parsimony*size) \t $(stringTree(member.tree))")
push!(dominating, member)
end
end
end
debug(verbosity, "")
# Migration
if migration
for j=1:nthreads
for k in rand(1:npop, Integer(npop*fractionReplaced))
# Copy in case one gets used twice
allPops[j].members[k] = deepcopy(bestPops.members[rand(1:size(bestPops.members)[1])])
end
end
end
# Hall of fame migration
if hofMigration
for j=1:nthreads
for k in rand(1:npop, Integer(npop*fractionReplacedHof))
# Copy in case one gets used twice
allPops[j].members[k] = deepcopy(dominating[rand(2:size(dominating)[1])])
end
end
end
end
end