memlnaut-nisps/nisps-core/include/nisps/dataset.hpp

196 lines
6.1 KiB
C++
Raw Normal View History

feat: extract nisps-core platform-agnostic ML library Extract the interactive machine learning engine from MEMLNaut-NISPS firmware into a standalone, platform-agnostic C++20 header-only library. What is nisps-core? ------------------- NISPS (Neural Interactive Shaping of Parameter Spaces) core is a parameter mapping engine. It takes N input parameters (joystick, sensors, audio features) and maps them to M output parameters through an interactively-trained neural network. Use it to control: synthesizers, effects, lights, robots, game parameters, or anything that responds to continuous control data. Key Features ------------ - Header-only: No compilation needed, just include and use - Platform-agnostic: Pure C++20, works anywhere - Zero dependencies: Only standard library - Interactive learning: Train by demonstration - Lightweight: ~3,500 lines of optimized neural network code - Flexible: Map 1-100 inputs to 1-100 outputs Architecture ------------ Core components: - IML: High-level interactive ML interface - MLP: Multi-layer perceptron (feedforward neural network) - Dataset: Training data management with replay memory - Layer/Node: Neural network building blocks - Loss: MSE and categorical cross-entropy functions - Utils: Activation functions (sigmoid, ReLU, tanh, etc.) Transformations Applied ----------------------- ✅ Removed Arduino/RP2040 dependencies (Serial, SD, Pico SDK) ✅ Removed audio synthesis code (nisps-core is control-only) ✅ Added nisps namespace to all code ✅ Converted to header-only library with _impl.hpp pattern ✅ Updated to C++20 (required for std::span) ✅ Removed platform-specific serialization ✅ Replaced debug macros with no-op stubs ✅ Added comprehensive documentation and examples Files Added ----------- - nisps-core/README.md: Complete documentation and API reference - nisps-core/CHANGELOG.md: Version history and migration guide - nisps-core/include/nisps/*.hpp: 13 header files (~3,500 lines) - nisps-core/test/main.cpp: XOR test demonstrating basic usage - nisps-core/examples/simple_mapping.cpp: Interactive demo - nisps-core/CMakeLists.txt: Build system for tests Testing ------- ✅ Compiles with GCC 14.2 (C++20) ✅ All tests passing ✅ Successfully instantiates networks and runs inference Performance ----------- - Inference: 1-10 µs for small networks (2-10-10-4) - Training: 10-100 ms for 100 examples, 1000 iterations - Memory: ~1 KB per hidden neuron Migration from Embedded IMLInterface ------------------------------------ Old (embedded): IMLInterface iml(n_inputs, n_outputs); New (nisps-core): nisps::IML<float> iml(n_inputs, n_outputs); All method names remain the same, just add the namespace. Related ------- - Implements: NISPS_CORE_EXTRACTION_PLAN.md - Task graph: NISPS_CORE_TASKS.md - Origin: MEMLNaut-NISPS firmware - Docs: https://musicallyembodiedml.github.io/memlnaut/ Co-authored-by: Claude Code <claude@anthropic.com>
2026-02-08 17:47:23 +01:00
/**
* @file dataset.hpp
* @brief Dataset management and replay memory functionality for NISPS
* @copyright Copyright (c) 2024. Licensed under Mozilla Public License Version 2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#ifndef NISPS_DATASET_HPP
#define NISPS_DATASET_HPP
#include <vector>
#include <cstdint>
#include <cstddef>
#include <utility>
#include <random>
#include <algorithm>
namespace nisps {
/**
* @brief Manages a dataset of feature-label pairs with optional replay memory functionality.
*
* This class provides dataset management capabilities including loading, storing, and sampling
* feature-label pairs. It includes legacy replay memory functionality which is now deprecated
* in favor of the ReplayMemory class.
*/
class Dataset {
public:
static constexpr size_t kMax_examples = 100;
using DatasetVector = std::vector<std::vector<float>>;
/**
* @brief Enumeration of forgetting modes for replay memory functionality.
* @deprecated Use ReplayMemory::FORGETMODES instead.
*/
enum ForgetMode {
FIFO, /**< First-In-First-Out: Removes the oldest item. */
RANDOM_EQUAL, /**< Random Equal: Removes a random item with equal probability. */
RANDOM_OLDER /**< Random Older: Removes an older item with higher probability. */
};
/**
* @brief Default constructor that initializes an empty dataset.
*/
Dataset();
/**
* @brief Constructs a dataset with initial feature and label vectors.
*
* @param features Vector of feature vectors to initialize with
* @param labels Vector of label vectors to initialize with
*/
Dataset(DatasetVector &features, DatasetVector &labels);
/**
* @brief Adds a new feature-label pair to the dataset.
*
* @param feature Vector containing input features
* @param label Vector containing output labels
* @return true if addition was successful, false otherwise
*/
bool Add(const std::vector<float> &feature, const std::vector<float> &label);
/**
* @brief Clears all data from the dataset.
*/
void Clear();
/**
* @brief Loads feature and label vectors into the dataset.
*
* @param features Vector of feature vectors to load
* @param labels Vector of label vectors to load
*/
void Load(DatasetVector &features, DatasetVector &labels);
/**
* @brief Provides direct access to internal feature and label vectors.
*
* @param features Pointer to feature vectors will be stored here
* @param labels Pointer to label vectors will be stored here
*/
void Fetch(DatasetVector *&features, DatasetVector *&labels);
/**
* @brief Returns a copy of the feature vectors, optionally with bias terms.
*
* @param with_bias If true, adds a bias term (1.0f) to each feature vector
* @return DatasetVector Copy of feature vectors with optional bias terms
*/
DatasetVector GetFeatures(bool with_bias = true);
/**
* @brief Returns a reference to the label vectors.
*
* @return DatasetVector& Reference to the label vectors
*/
DatasetVector &GetLabels();
/**
* @brief Returns the size of feature vectors, accounting for optional bias term.
*
* @param with_bias If true, includes the bias term in the size
* @return size_t Size of feature vectors
*/
inline size_t GetFeatureSize(bool with_bias = true) { return data_size_ + with_bias; }
/**
* @brief Returns the size of label vectors.
*
* @return size_t Size of label vectors
*/
inline size_t GetOutputSize() { return output_size_; }
/**
* @brief Enables or disables replay memory functionality.
* @deprecated Use ReplayMemory class instead.
*
* @param enabled True to enable replay memory, false to disable
*/
void ReplayMemory(bool enabled);
/**
* @brief Sets the forgetting mode for replay memory.
* @deprecated Use ReplayMemory::FORGETMODES instead.
*
* @param mode The forgetting mode to use
*/
void SetForgetMode(ForgetMode mode);
/**
* @brief Sets the maximum number of examples in the dataset.
*
* @param max Maximum number of examples to store
*/
void SetMaxExamples(size_t max);
/**
* @brief Samples from the dataset, optionally with bias terms.
* @deprecated Use ReplayMemory::sample() instead for replay memory functionality.
*
* @param with_bias If true, adds bias terms to feature vectors
* @return std::pair<DatasetVector, DatasetVector> Pair of feature and label vectors
*/
std::pair<DatasetVector, DatasetVector> Sample(bool with_bias = true);
protected:
size_t data_size_;
size_t output_size_;
inline void _InitSizes() { data_size_ = 0; output_size_ = 0; }
void _AdjustSizes();
DatasetVector features_;
DatasetVector labels_;
private:
/**
* @brief Utility static method that returns a copy of the given feature vectors,
* adding a bias term (1.0f) to each vector if with_bias is true.
*
* @param features Feature vectors to copy
* @param with_bias If true, adds a bias term to each vector
* @return DatasetVector Copy of feature vectors with optional bias terms
*/
static DatasetVector AddBias(const DatasetVector &features, bool with_bias);
/**
* @brief Removes one excess example based on the current forget mode.
*/
void RemoveOneExcessExample();
// Replay memory functionality flag.
bool replay_memory_enabled_ = false;
std::mt19937 rng_;
// Additional members for extended replay memory functionality:
// Timestamps for each example (used in RANDOM_OLDER mode).
std::vector<size_t> timestamps_;
size_t current_timestamp_ = 0;
// Current forgetting mode.
ForgetMode forget_mode_ = FIFO;
// Maximum number of examples allowed.
size_t max_examples_;
};
} // namespace nisps
#include "dataset_impl.hpp"
#endif // NISPS_DATASET_HPP