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))
166 opt->n_params = n_params;
170 opt->n_cand = n_cand;
174 opt->n_best = n_best;
177 if((mutation_amp > 1) || (mutation_amp < 0))
179 if(mutation_amp <= 0.001f)
180 mutation_amp = 0.001f;
181 opt->mutation_amp = mutation_amp;
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;
195 opt->candidates[i][j] = base + noise;
196 if (opt->candidates[i][j] < 0.0f) opt->candidates[i][j] = 0.0f;
197 if (opt->candidates[i][j] > 1.0f) opt->candidates[i][j] = 1.0f;
228 if((opt == NULL) || (params == NULL))
231 uint16_t n_params = opt->n_params;
235 uint16_t n_cand = opt->n_cand;
239 uint16_t n_best = opt->n_best;
243 float mut = opt->mutation_amp;
244 if((mut > 1) ||(mut < 0))
248 opt->loss[opt->cand_index] = loss;
251 if (opt->cand_index >= n_cand) {
253 for(uint16_t i = 0; i < opt->n_cand; i++)
254 opt->sorted_idx[i] = i;
257 qsort(opt->sorted_idx, opt->n_cand,
sizeof(uint16_t), cmp_idx);
261 float best_loss = opt->loss[opt->sorted_idx[0]];
262 float worst_loss = opt->loss[opt->sorted_idx[opt->n_cand - 1]];
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));
279 if(opt->stability < 0.0f) opt->stability = 0.0f;
280 if(opt->stability > 1.0f) opt->stability = 1.0f;
282 float mut_pct = GEN_MUTATION_MIN_PCT +
283 (GEN_MUTATION_MAX_PCT - GEN_MUTATION_MIN_PCT) * loss_ratio;
284 float adaptive_mut = mut * (mut_pct / 100.0f);
285 if (adaptive_mut < 0.0001f) adaptive_mut = 0.0001f;
286 opt->gen_mut = adaptive_mut;
289 uint16_t n_elite = ELOVLE_N_ELITE_CANDIDATE;
290 for (uint16_t c = 0; c < n_cand; c++) {
292 for (uint16_t i = 0; i < n_params; i++)
293 opt->candidates[c][i] = opt->candidates[opt->sorted_idx[c]][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;
299 uint16_t parent = opt->sorted_idx[rand() % opt->n_best];
300 opt->candidates[c][i] = opt->candidates[parent][i] + noise;
301 if (opt->candidates[c][i] < 0.0f) opt->candidates[c][i] = 0.0f;
302 if (opt->candidates[c][i] > 1.0f) opt->candidates[c][i] = 1.0f;
312 for (uint16_t i = 0; i < opt->n_params; i++)
313 params[i] = opt->candidates[opt->cand_index][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
Максимальное количество параметров
#define local_time()
Локальное время
Заголочный файл для дефайнов библиотеки MyLibsGeneral.