62#ifndef __EVOLVE_OPTIMIZER_H_
63#define __EVOLVE_OPTIMIZER_H_
69#ifdef ENABLE_EVOLVE_OPTIMIZATION
73#define PARAM_SCALE(x, min_val, max_val) \
74(((float)(x) - (float)(min_val)) / ((float)(max_val) - (float)(min_val)))
79#define PARAM_UNSCALE(val, min_val, max_val) \
80(((float)(val)) * ((float)(max_val) - (float)(min_val)) + (float)(min_val))
83#define local_time() HAL_GetTick()
88#ifndef EVOLVE_MUTATION_MIN_PCT
89#define EVOLVE_MUTATION_MIN_PCT 10
91#ifndef EVOLVE_MUTATION_MAX_PCT
92#define EVOLVE_MUTATION_MAX_PCT 100
94#ifndef ELOVLE_N_ELITE_CANDIDATE
95#define ELOVLE_N_ELITE_CANDIDATE 2
124static int cmp_idx(
const void *a,
const void *b) {
125 if (g_sort_opt->
loss[*(
const uint16_t*)a] < g_sort_opt->
loss[*(
const uint16_t*)b])
127 if (g_sort_opt->
loss[*(
const uint16_t*)a] > g_sort_opt->
loss[*(
const uint16_t*)b])
155 if((opt == NULL) || (start_params == NULL))
171 if((mutation_amp > 1) || (mutation_amp < 0))
173 if(mutation_amp <= 0.001f)
174 mutation_amp = 0.001f;
179 seed += (ADC1->DR & 0xFF);
183 for (uint16_t i = 0; i < n_cand; i++) {
184 for (uint16_t j = 0; j < n_params; j++) {
186 float base = start_params[j];
187 float inv_randmax = 1.0f / (float)RAND_MAX;
188 float noise = ((float)rand() * inv_randmax * 2.0f - 1.0f) * mutation_amp;
220 if((opt == NULL) || (params == NULL))
227 uint16_t n_cand = opt->
n_cand;
231 uint16_t n_best = opt->
n_best;
236 if((mut > 1) ||(mut < 0))
245 for(uint16_t i = 0; i < opt->
n_cand; i++)
255 float diff = worst_loss - best_loss;
257 float sum_loss = 0.0f;
258 for (uint16_t i = 0; i < n_cand; i++)
259 sum_loss += opt->
loss[i];
260 float avg_loss = sum_loss / (float)n_cand;
263 float loss_ratio = (diff > 0.0f) ? ((avg_loss - best_loss) / diff) : 0.5f;
264 if (loss_ratio < 0.0f) loss_ratio = 0.0f;
265 if (loss_ratio > 1.0f) loss_ratio = 1.0f;
268 if(diff < 0.0f) diff = 0.0f;
269 if(diff > 1.0f) diff = 1.0f;
270 opt->
stability = (1.0f - worst_loss) * (1.0f - (worst_loss - best_loss));
276 float adaptive_mut = mut * (mut_pct / 100.0f);
277 if (adaptive_mut < 0.0001f) adaptive_mut = 0.0001f;
281 for (uint16_t c = 0; c < n_cand; c++) {
283 for (uint16_t i = 0; i < n_params; i++)
287 for (uint16_t i = 0; i < n_params; i++) {
288 float inv_randmax = 1.0f / (float)RAND_MAX;
289 float noise = ((float)rand() * inv_randmax * 2.0f - 1.0f) * adaptive_mut;
302 for (uint16_t i = 0; i < opt->
n_params; i++)
315 float candidates[0][0];
317#define EvolveOptimizer_Init(opt, n_params, n_cand, n_best, mutation_amp, start_params)
318#define EvolveOptimizer_Step(opt, params, LossFunc)
319#define PARAM_SCALE(x, min_val, max_val) (x)
320#define PARAM_UNSCALE(val, min_val, max_val) (val)
#define EVOLVE_MAX_CANDIDATES
Максимальное количество кандидатов для обучения
#define EVOLVE_MAX_PARAMS
Максимальное количество параметров
#define EVOLVE_MUTATION_MIN_PCT
Минимальная мутация (в процентах от Loss)
#define ELOVLE_N_ELITE_CANDIDATE
Количество кандидатов, которые проходят в поколение без изменений (по умолчанию 2)
__STATIC_INLINE int EvolveOptimizer_Init(EvolveOptimizer_t *opt, uint16_t n_params, uint16_t n_cand, uint16_t n_best, float mutation_amp, float *start_params)
Инициализация эволюционного оптимизатора.
#define EVOLVE_MUTATION_MAX_PCT
Максимальная мутация (в процентах от Loss)
#define local_time()
Локальное время
__STATIC_INLINE int EvolveOptimizer_Step(EvolveOptimizer_t *opt, float *params, float loss)
Один шаг эволюционного оптимизатора.
Заголочный файл для дефайнов библиотеки MyLibsGeneral.
Структура эволюционного оптимизатора
uint16_t cand_index
Индекс кандидата для обработки
uint16_t n_params
Количество параметров
uint16_t sorted_idx[100]
Индексы отсортированных кандидатов
float stability
Коэффициент насколько стабильная популяция (0..1)(n_cand)
float loss[100]
Loss для каждого кандидата
uint16_t n_best
Количество лучших, усредняемых
uint16_t n_cand
Количество кандидатов в популяции
float candidates[100][20]
Параметры кандидатов
float mutation_amp
Амплитуда мутации (0..1)