MilesCranmer commited on
Commit
d3ad40f
·
1 Parent(s): b13cd33

Speedup with annealing turned off

Browse files
Files changed (5) hide show
  1. README.md +5 -0
  2. benchmark.jl +17 -1
  3. benchmarktimes.txt +1 -0
  4. eureqa.jl +20 -20
  5. paralleleureqa.jl +0 -1
README.md CHANGED
@@ -89,4 +89,9 @@ weights = [8, 1, 1, 1, 2]
89
  - [ ] Use NN to generate weights over all probability distribution, and train on some randomly-generated equations
90
  - [ ] Performance:
91
  - Use an enum for functions instead of storing them?
 
 
 
 
 
92
 
 
89
  - [ ] Use NN to generate weights over all probability distribution, and train on some randomly-generated equations
90
  - [ ] Performance:
91
  - Use an enum for functions instead of storing them?
92
+ - Current most expensive operations:
93
+ - deepcopy() before the mutate, to see whether to accept or not.
94
+ - (This is only for simulated annealing... but generally we don't need to use this)
95
+ - Calculating the loss function - there is duplicate calculations happening.
96
+ - Declaration of the weights array every iteration
97
 
benchmark.jl CHANGED
@@ -1,6 +1,13 @@
1
  include("paralleleureqa.jl")
2
  using BenchmarkTools
3
 
 
 
 
 
 
 
 
4
  t = @benchmark(fullRun(3,
5
  npop=100,
6
  annealing=true,
@@ -9,4 +16,13 @@ t = @benchmark(fullRun(3,
9
  verbosity=0
10
  ), evals=5)
11
 
12
- println("The median time is $(median(t))")
 
 
 
 
 
 
 
 
 
 
1
  include("paralleleureqa.jl")
2
  using BenchmarkTools
3
 
4
+ fullRun(3,
5
+ npop=100,
6
+ annealing=true,
7
+ ncyclesperiteration=100,
8
+ fractionReplaced=0.1f0,
9
+ verbosity=0)
10
+
11
  t = @benchmark(fullRun(3,
12
  npop=100,
13
  annealing=true,
 
16
  verbosity=0
17
  ), evals=5)
18
 
19
+ tnoanneal = @benchmark(fullRun(3,
20
+ npop=100,
21
+ annealing=false,
22
+ ncyclesperiteration=100,
23
+ fractionReplaced=0.1f0,
24
+ verbosity=0
25
+ ), evals=5)
26
+
27
+ println("The median time is $(median(t)) with annealing, $(median(tnoanneal)) without")
28
+
benchmarktimes.txt CHANGED
@@ -1,2 +1,3 @@
1
  The median time is TrialEstimate(3.136 s)
2
  The median time is TrialEstimate(435.125 ms)
 
 
1
  The median time is TrialEstimate(3.136 s)
2
  The median time is TrialEstimate(435.125 ms)
3
+ The median time is TrialEstimate(422.519 ms) with annealing, TrialEstimate(361.631 ms) without
eureqa.jl CHANGED
@@ -332,9 +332,12 @@ function iterate(
332
  tree::Node, T::Float32,
333
  X::Array{Float32, 2}, y::Array{Float32, 1},
334
  alpha::Float32=1.0f0,
335
- mult::Float32=0.1f0
 
336
  )::Node
337
- prev = deepcopy(tree)
 
 
338
 
339
  mutationChoice = rand()
340
  weight_for_constant = min(8, countConstants(tree))
@@ -355,7 +358,7 @@ function iterate(
355
  tree = tree
356
  end
357
 
358
- try
359
  beforeLoss = scoreFunc(prev, X, y, parsimony=mult)
360
  afterLoss = scoreFunc(tree, X, y, parsimony=mult)
361
  delta = afterLoss - beforeLoss
@@ -364,17 +367,9 @@ function iterate(
364
  if isnan(afterLoss) || probChange < rand()
365
  return prev
366
  end
367
-
368
- return tree
369
-
370
- catch error
371
- # Sometimes too many chained exp operators
372
- if isa(error, DomainError)
373
- return prev
374
- else
375
- throw(error)
376
- end
377
  end
 
 
378
  end
379
 
380
  # Create a random equation by appending random operators
@@ -429,9 +424,13 @@ function bestSubPop(pop::Population)::Population
429
  end
430
 
431
  # Mutate the best sampled member of the population
432
- function iterateSample(pop::Population, T::Float32)::PopMember
 
 
433
  allstar = bestOfSample(pop)
434
- new = iterate(allstar.tree, T, X, y, alpha, parsimony)
 
 
435
  allstar.tree = new
436
  allstar.score = scoreFunc(new, X, y, parsimony=parsimony)
437
  allstar.birth = round(Int32, 1e3*(time()-1.6e9))
@@ -440,9 +439,11 @@ end
440
 
441
  # Pass through the population several times, replacing the oldest
442
  # with the fittest of a small subsample
443
- function regEvolCycle(pop::Population, T::Float32)::Population
 
 
444
  for i=1:Integer(pop.n/ns)
445
- baby = iterateSample(pop, T)
446
  #printTree(baby.tree)
447
  oldest = argmin([pop.members[member].birth for member=1:pop.n])
448
  pop.members[oldest] = baby
@@ -458,14 +459,13 @@ function run(
458
  annealing::Bool=false;
459
  verbosity::Integer=0
460
  )::Population
461
- pop = deepcopy(pop)
462
 
463
  allT = LinRange(1.0f0, 0.0f0, ncycles)
464
  for iT in 1:size(allT)[1]
465
  if annealing
466
- pop = regEvolCycle(pop, allT[iT])
467
  else
468
- pop = regEvolCycle(pop, 1.0f0)
469
  end
470
  if verbosity > 0 && (iT % verbosity == 0)
471
  bestPops = bestSubPop(pop)
 
332
  tree::Node, T::Float32,
333
  X::Array{Float32, 2}, y::Array{Float32, 1},
334
  alpha::Float32=1.0f0,
335
+ mult::Float32=0.1f0;
336
+ annealing::Bool=true
337
  )::Node
338
+ if annealing
339
+ prev = deepcopy(tree)
340
+ end
341
 
342
  mutationChoice = rand()
343
  weight_for_constant = min(8, countConstants(tree))
 
358
  tree = tree
359
  end
360
 
361
+ if annealing
362
  beforeLoss = scoreFunc(prev, X, y, parsimony=mult)
363
  afterLoss = scoreFunc(tree, X, y, parsimony=mult)
364
  delta = afterLoss - beforeLoss
 
367
  if isnan(afterLoss) || probChange < rand()
368
  return prev
369
  end
 
 
 
 
 
 
 
 
 
 
370
  end
371
+
372
+ return tree
373
  end
374
 
375
  # Create a random equation by appending random operators
 
424
  end
425
 
426
  # Mutate the best sampled member of the population
427
+ function iterateSample(
428
+ pop::Population, T::Float32;
429
+ annealing::Bool=true)::PopMember
430
  allstar = bestOfSample(pop)
431
+ new = iterate(
432
+ allstar.tree, T, X, y,
433
+ alpha, parsimony, annealing=annealing)
434
  allstar.tree = new
435
  allstar.score = scoreFunc(new, X, y, parsimony=parsimony)
436
  allstar.birth = round(Int32, 1e3*(time()-1.6e9))
 
439
 
440
  # Pass through the population several times, replacing the oldest
441
  # with the fittest of a small subsample
442
+ function regEvolCycle(
443
+ pop::Population, T::Float32;
444
+ annealing::Bool=true)::Population
445
  for i=1:Integer(pop.n/ns)
446
+ baby = iterateSample(pop, T, annealing=annealing)
447
  #printTree(baby.tree)
448
  oldest = argmin([pop.members[member].birth for member=1:pop.n])
449
  pop.members[oldest] = baby
 
459
  annealing::Bool=false;
460
  verbosity::Integer=0
461
  )::Population
 
462
 
463
  allT = LinRange(1.0f0, 0.0f0, ncycles)
464
  for iT in 1:size(allT)[1]
465
  if annealing
466
+ pop = regEvolCycle(pop, allT[iT], annealing=true)
467
  else
468
+ pop = regEvolCycle(pop, 1.0f0, annealing=true)
469
  end
470
  if verbosity > 0 && (iT % verbosity == 0)
471
  bestPops = bestSubPop(pop)
paralleleureqa.jl CHANGED
@@ -36,4 +36,3 @@ function fullRun(niterations::Integer;
36
  end
37
  end
38
  end
39
-
 
36
  end
37
  end
38
  end