61#ifndef __GEN_OPTIMIZER_H_
62#define __GEN_OPTIMIZER_H_
68#ifdef GEN_OPTIMIZATION_ENABLE
72#define PARAM_SCALE(x, min_val, max_val) \
73(((float)(x) - (float)(min_val)) / ((float)(max_val) - (float)(min_val)))
78#define PARAM_UNSCALE(val, min_val, max_val) \
79(((float)(val)) * ((float)(max_val) - (float)(min_val)) + (float)(min_val))
82#define local_time() HAL_GetTick()
87#ifndef GEN_MUTATION_MIN_PCT
88#define GEN_MUTATION_MIN_PCT 10
90#ifndef GEN_MUTATION_MAX_PCT
91#define GEN_MUTATION_MAX_PCT 100
93#ifndef ELOVLE_N_ELITE_CANDIDATE
94#define ELOVLE_N_ELITE_CANDIDATE 2
130static int cmp_idx(
const void *a,
const void *b) {
131 if (g_sort_opt->
loss[*(
const uint16_t*)a] < g_sort_opt->
loss[*(
const uint16_t*)b])
133 if (g_sort_opt->
loss[*(
const uint16_t*)a] > g_sort_opt->
loss[*(
const uint16_t*)b])
161 if((opt == NULL) || (start_params == NULL))
177 if((mutation_amp > 1) || (mutation_amp < 0))
179 if(mutation_amp <= 0.001f)
180 mutation_amp = 0.001f;
185 seed += (ADC1->DR & 0xFF);
189 for (uint16_t i = 0; i < n_cand; i++) {
190 for (uint16_t j = 0; j < n_params; j++) {
192 float base = start_params[j];
193 float inv_randmax = 1.0f / (float)RAND_MAX;
194 float noise = ((float)rand() * inv_randmax * 2.0f - 1.0f) * mutation_amp;
228 if((opt == NULL) || (params == NULL))
235 uint16_t n_cand = opt->
n_cand;
239 uint16_t n_best = opt->
n_best;
244 if((mut > 1) ||(mut < 0))
253 for(uint16_t i = 0; i < opt->
n_cand; i++)
263 float diff = worst_loss - best_loss;
265 float sum_loss = 0.0f;
266 for (uint16_t i = 0; i < n_cand; i++)
267 sum_loss += opt->
loss[i];
268 float avg_loss = sum_loss / (float)n_cand;
271 float loss_ratio = (diff > 0.0f) ? ((avg_loss - best_loss) / diff) : 0.5f;
272 if (loss_ratio < 0.0f) loss_ratio = 0.0f;
273 if (loss_ratio > 1.0f) loss_ratio = 1.0f;
276 if(diff < 0.0f) diff = 0.0f;
277 if(diff > 1.0f) diff = 1.0f;
278 opt->
stability = (1.0f - worst_loss) * (1.0f - (worst_loss - best_loss));
284 float adaptive_mut = mut * (mut_pct / 100.0f);
285 if (adaptive_mut < 0.0001f) adaptive_mut = 0.0001f;
290 for (uint16_t c = 0; c < n_cand; c++) {
292 for (uint16_t i = 0; i < n_params; i++)
296 for (uint16_t i = 0; i < n_params; i++) {
297 float inv_randmax = 1.0f / (float)RAND_MAX;
298 float noise = ((float)rand() * inv_randmax * 2.0f - 1.0f) * adaptive_mut;
312 for (uint16_t i = 0; i < opt->
n_params; i++)
325 float candidates[0][0];
327#define GenOptimizer_Init(opt, n_params, n_cand, n_best, mutation_amp, start_params)
328#define GenOptimizer_Step(opt, params, LossFunc)
329#define PARAM_SCALE(x, min_val, max_val) (x)
330#define PARAM_UNSCALE(val, min_val, max_val) (val)
#define GEN_MAX_CANDIDATES
Максимальное количество кандидатов для обучения
#define GEN_MAX_PARAMS
Максимальное количество параметров
static int GenOptimizer_Init(GenOptimizer_t *opt, uint16_t n_params, uint16_t n_cand, uint16_t n_best, float mutation_amp, float *start_params)
Инициализация эволюционного оптимизатора.
#define ELOVLE_N_ELITE_CANDIDATE
Количество кандидатов, которые проходят в поколение без изменений (по умолчанию 2)
#define GEN_MUTATION_MIN_PCT
Минимальная мутация (в процентах от Loss)
#define GEN_MUTATION_MAX_PCT
Максимальная мутация (в процентах от Loss)
static int GenOptimizer_Step(GenOptimizer_t *opt, float *params, float loss)
Один шаг эволюционного оптимизатора.
#define local_time()
Локальное время
Заголочный файл для дефайнов библиотеки MyLibsGeneral.
Структура эволюционного оптимизатора
uint16_t cand_index
Индекс текущего кандидата
uint16_t sorted_idx[GEN_MAX_CANDIDATES]
Индексы отсортированных кандидатов
uint16_t n_best
Количество лучших, усредняемых
uint16_t gen_index
Индекс популяции
uint16_t n_cand
Количество кандидатов в популяции
float stability
Коэффициент насколько стабильная популяция (0..1)(n_cand)
float gen_mut
Амплитуда мутации у текущей популяции
float mutation_amp
Амплитуда мутации (0..1)
float loss[GEN_MAX_CANDIDATES]
Loss для каждого кандидата
float candidates[GEN_MAX_CANDIDATES][GEN_MAX_PARAMS]
Параметры кандидатов
uint16_t n_params
Количество параметров