13#if !defined(ULTRA_SEARCH_H)
14# error "Don't include this file directly, include the specific .h instead"
17#if !defined(ULTRA_SEARCH_TCC)
18#define ULTRA_SEARCH_TCC
26template<
template<
class>
class ES, Evaluator E>
27basic_search<ES, E>::basic_search(problem &prob, E eva)
28 : eva_(
std::move(eva), prob.params.cache.size), prob_(prob)
44template<
template<
class>
class ES, Evaluator E>
45void basic_search<ES, E>::init()
50 ultraINFO(
"Init continues without cache");
53template<
template<
class>
class ES, Evaluator E>
54basic_search<ES, E> &basic_search<ES, E>::messages(
bool m)
noexcept
72template<
template<
class>
class ES, Evaluator E>
73basic_search<ES, E> &basic_search<ES, E>::stop_source(std::stop_source ss)
90template<
template<
class>
class ES, Evaluator E>
91basic_search<ES, E> &basic_search<ES, E>::logger(search_log &sl)
noexcept
107template<
template<
class>
class ES, Evaluator E>
108basic_search<ES, E> &basic_search<ES, E>::tag(
const std::string &t)
121template<
template<
class>
class ES, Evaluator E>
122void basic_search<ES, E>::after_evolution(
123 unsigned run,
const std::vector<model_measurements<fitness_t>> &mm)
127 static const std::vector<std::string> phase_names {
"TRAINING",
"VALIDATION"};
129 const std::string tags(tag_.empty() ? tag_ :
"[" + tag_ +
"] ");
131 for (std::size_t i(0);
const auto &m : mm)
135 accuracy = std::format(
"{:.6g}%", *m.accuracy * 100.0);
139 const auto phase(mm.size() <= phase_names.size()
140 ? phase_names[i] :
"PHASE" + std::to_string(i));
142 ultraPAROUT(
"{}Run {} {}. Fitness: {} Accuracy: {}",
143 tags, run, phase, internal::streamed(*m.fitness), accuracy);
150template<
template<
class>
class ES, Evaluator E>
151basic_search<ES, E> &basic_search<ES, E>::refinement(refinement_callback_t f)
153 refinement_callback_ = std::move(f);
164template<
template<
class>
class ES, Evaluator E>
165basic_search<ES, E> &basic_search<ES, E>::after_generation(
166 after_generation_callback_t f)
168 after_generation_callback_ = std::move(f);
179template<
template<
class>
class ES, Evaluator E>
180basic_search<ES, E> &basic_search<ES, E>::on_training_new_best(
181 on_training_new_best_callback_t f)
183 on_training_new_best_callback_ = std::move(f);
196template<
template<
class>
class ES, Evaluator E>
197void basic_search<ES, E>::tune_parameters()
199 auto ¶ms(prob_.params);
203 const auto dflt(ES<E>::shape(parameters().init()));
204 assert(!dflt.needs_init());
207 const auto constrained(params);
209 params.fill_undefined_from(dflt);
211 if (!constrained.evolution.mate_zone)
212 params.evolution.mate_zone =
213 std::max<std::size_t>(params.population.individuals / 5, 4);
215 Ensures(params.is_valid(
true));
226template<
template<
class>
class ES, Evaluator E>
227search_stats<typename basic_search<ES, E>::individual_t,
228 typename basic_search<ES, E>::fitness_t>
229basic_search<ES, E>::run(
unsigned n,
230 const model_measurements<fitness_t> &threshold)
234 shake_function_callback_t shake([
this](
unsigned g) {
return vs_->shake(g); });
235 search_stats<individual_t, fitness_t> stats;
237 for (
unsigned r(0); r < n && !stop_source_.stop_requested(); ++r)
239 if (vs_->training_setup(r) == evaluation_context::changed)
242 evolution evo(prob_, eva_);
244 evo.logger(*search_log_);
245 evo.after_generation(after_generation_callback_)
246 .messages(emit_messages_)
247 .on_new_best(on_training_new_best_callback_)
248 .refinement(refinement_callback_)
249 .shake_function(shake)
250 .stop_source(stop_source_)
253 const auto run_summary(evo.template run<ES>());
255 if (
const auto prg(run_summary.best().ind); !prg.empty())
257 std::vector metrics = { calculate_metrics(prg) };
259 if (vs_->validation_setup(r))
260 metrics.push_back(calculate_metrics(prg));
262 after_evolution(r, metrics);
265 stats.update(prg, metrics.back(), run_summary.elapsed);
269 search_log_->save_summary(stats, threshold);
287template<
template<
class>
class ES, Evaluator E>
288model_measurements<typename basic_search<ES, E>::fitness_t>
289basic_search<ES, E>::calculate_metrics(
const individual_t &prg)
const
291 model_measurements<fitness_t> ret;
295 ret.fitness = eva_.core()(prg);
306template<
template<
class>
class ES, Evaluator E>
307template<ValidationStrategy V,
class... Args>
310 vs_ = std::make_unique<V>(std::forward<Args>(args)...);
320template<
template<
class>
class ES,
Evaluator E>
337template<
template<
class>
class ES,
Evaluator E>
338bool basic_search<ES, E>::load()
340 const auto &file(prob_.params.cache.serialization_file);
345 if (!prob_.params.cache.size)
347 ultraINFO(
"Cache size is 0; skipping cache load from {}", file.string());
351 std::ifstream in(file);
354 ultraWARNING(
"Cannot open cache file {}", file.string());
358 if (!eva_.load_cache(in))
360 ultraWARNING(
"Cannot load cache from {}", file.string());
364 ultraINFO(
"Loaded cache from {}", file.string());
371template<
template<
class>
class ES, Evaluator E>
372bool basic_search<ES, E>::is_valid()
const
basic_search(problem &, E)
Definition search.h:28
Definition validation_strategy.h:29
Definition evaluator.h:44
bool load(std::istream &in, F *f)
Definition fitness.tcc:190
double accuracy(const P &p, const dataframe &d)
Definition metrics.h:47
void invalidate_cache_if_supported(E &eva)
Definition evaluation_context.h:48