Phase 6 — State persistence: - Full state serialization: version, weights (3D), examples (features+labels), mlpConfig, noiseLevel, slewMs, output/input ranges - Validation on load: version check, graceful missing field handling - .nisps preset save/load via right-click menu (osdialog file dialogs) - Param values included in preset files Phase 7 — Derived outputs: - Mean, STD, delta computed on audio thread (trivial cost) - Novelty/confidence: nearest_example_distance() computed on background thread after each training/perturbation job, cached for audio thread - Defaults with 0 examples: novelty=10V, confidence=0V nisps-core IML additions: - get_weights() / set_weights() for MLP weight serialization - get_example_features/labels() / load_examples() for dataset serialization - nearest_example_distance() for novelty/confidence metric - get_example_count() / get_max_examples() for UI display
111 lines
3.4 KiB
C++
111 lines
3.4 KiB
C++
#ifndef NISPS_IML_HPP
|
|
#define NISPS_IML_HPP
|
|
|
|
#include "mlp.hpp"
|
|
#include "dataset.hpp"
|
|
#include <vector>
|
|
#include <cstddef>
|
|
#include <functional>
|
|
|
|
namespace nisps {
|
|
|
|
template<typename Float = float>
|
|
class IML {
|
|
public:
|
|
enum class Mode { Inference, Training };
|
|
|
|
using LogFn = void(*)(const char*);
|
|
|
|
IML(size_t n_inputs, size_t n_outputs,
|
|
std::vector<size_t> hidden_layers = {10, 10, 14},
|
|
size_t max_iterations = 1000,
|
|
Float learning_rate = 1.0f,
|
|
Float convergence_threshold = 0.00001f);
|
|
|
|
// Input
|
|
void set_input(size_t index, Float value);
|
|
void set_inputs(const Float* values, size_t count);
|
|
|
|
// Output (valid after process())
|
|
const Float* get_outputs() const;
|
|
size_t num_inputs() const { return n_inputs_; }
|
|
size_t num_outputs() const { return n_outputs_; }
|
|
|
|
// Set outputs directly (for programmatic training without hardware)
|
|
void set_output(size_t index, Float value);
|
|
void set_outputs(const Float* values, size_t count);
|
|
|
|
// Runtime
|
|
void process();
|
|
|
|
// Training workflow
|
|
void set_mode(Mode mode);
|
|
Mode get_mode() const { return mode_; }
|
|
void save_example();
|
|
void add_example(const Float* inputs, size_t n_in, const Float* outputs, size_t n_out);
|
|
void clear_dataset();
|
|
void randomise_weights();
|
|
|
|
// Spread-aware weight randomization
|
|
// spread: 0 = uniform [-1,1], 1 = Xavier-scaled per layer
|
|
void randomise_weights(Float spread);
|
|
|
|
// Spread-aware weight perturbation (for RL exploration)
|
|
// speed: noise magnitude, spread: 0 = flat noise, 1 = Xavier-scaled + weight decay
|
|
void move_weights(Float speed, Float spread);
|
|
|
|
// ── Serialization accessors ───────────────────────────────────────
|
|
|
|
// Weight access (delegates to MLP)
|
|
typename MLP<Float>::mlp_weights get_weights() const;
|
|
void set_weights(typename MLP<Float>::mlp_weights& weights);
|
|
|
|
// Dataset access
|
|
size_t get_example_count() const;
|
|
size_t get_max_examples() const;
|
|
// Returns copies of the dataset vectors
|
|
std::vector<std::vector<Float>> get_example_features() const;
|
|
std::vector<std::vector<Float>> get_example_labels() const;
|
|
// Bulk-load examples (clears existing, adds all)
|
|
void load_examples(const std::vector<std::vector<Float>>& features,
|
|
const std::vector<std::vector<Float>>& labels);
|
|
|
|
// Nearest-neighbor distance for novelty/confidence computation
|
|
// Returns the minimum Euclidean distance from `input` to any training example
|
|
Float nearest_example_distance(const Float* input, size_t n_in) const;
|
|
|
|
// Optional logging
|
|
void set_logger(LogFn fn) { log_fn_ = fn; }
|
|
|
|
private:
|
|
void log(const char* msg) const {
|
|
if (log_fn_) log_fn_(msg);
|
|
}
|
|
void train();
|
|
|
|
size_t n_inputs_;
|
|
size_t n_outputs_;
|
|
size_t max_iterations_;
|
|
Float learning_rate_;
|
|
Float convergence_threshold_;
|
|
|
|
Mode mode_ = Mode::Inference;
|
|
bool input_updated_ = false;
|
|
bool perform_inference_ = true;
|
|
|
|
std::vector<Float> input_state_;
|
|
std::vector<Float> output_state_;
|
|
|
|
std::unique_ptr<Dataset> dataset_;
|
|
std::unique_ptr<MLP<Float>> mlp_;
|
|
typename MLP<Float>::mlp_weights stored_weights_;
|
|
bool weights_randomised_ = false;
|
|
|
|
LogFn log_fn_ = nullptr;
|
|
};
|
|
|
|
} // namespace nisps
|
|
|
|
#include "iml_impl.hpp"
|
|
|
|
#endif // NISPS_IML_HPP
|