From 126bac8c1a97a15a0675871cdc0c3e863fc23830 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 19:45:21 +0200 Subject: [PATCH 1/8] stubs: Remove outdated comment about .py file ending --- stubs/emlearn_arrayutils.pyi | 2 -- stubs/emlearn_cnn.pyi | 1 - stubs/emlearn_fft.pyi | 1 - stubs/emlearn_iir.pyi | 1 - stubs/emlearn_linreg.pyi | 1 - stubs/emlearn_neighbors.pyi | 1 - stubs/emlearn_trees.pyi | 1 - 7 files changed, 8 deletions(-) diff --git a/stubs/emlearn_arrayutils.pyi b/stubs/emlearn_arrayutils.pyi index 4e786923..32f11218 100644 --- a/stubs/emlearn_arrayutils.pyi +++ b/stubs/emlearn_arrayutils.pyi @@ -1,6 +1,4 @@ - # Stub file (PEP 484) with API definitions and documentation for native module -# Is called .py because Sphinx autodoc currently does not support .pyi files """ Array utility functions diff --git a/stubs/emlearn_cnn.pyi b/stubs/emlearn_cnn.pyi index fe39c2cc..391f6940 100644 --- a/stubs/emlearn_cnn.pyi +++ b/stubs/emlearn_cnn.pyi @@ -1,5 +1,4 @@ # Stub file (PEP 484) with API definitions and documentation for native module -# Is called .py because Sphinx autodoc currently does not support .pyi files """ Convolutional Neural Network module. diff --git a/stubs/emlearn_fft.pyi b/stubs/emlearn_fft.pyi index 4c077629..8f601e0c 100644 --- a/stubs/emlearn_fft.pyi +++ b/stubs/emlearn_fft.pyi @@ -1,6 +1,5 @@ # Stub file (PEP 484) with API definitions and documentation for native module -# Is called .py because Sphinx autodoc currently does not support .pyi files """ Fast Fourier Transform (FFT) diff --git a/stubs/emlearn_iir.pyi b/stubs/emlearn_iir.pyi index ebe8843b..590ca118 100644 --- a/stubs/emlearn_iir.pyi +++ b/stubs/emlearn_iir.pyi @@ -1,6 +1,5 @@ # Stub file (PEP 484) with API definitions and documentation for native module -# Is called .py because Sphinx autodoc currently does not support .pyi files """ Infinite Impulse Response (IIR) filters diff --git a/stubs/emlearn_linreg.pyi b/stubs/emlearn_linreg.pyi index b23feadf..9667a471 100644 --- a/stubs/emlearn_linreg.pyi +++ b/stubs/emlearn_linreg.pyi @@ -1,5 +1,4 @@ # Stub file (PEP 484) with API definitions and documentation for native module -# Is called .py because Sphinx autodoc currently does not support .pyi files """ Linear Regression with support for training/learning/fitting as well as inference/predictions. diff --git a/stubs/emlearn_neighbors.pyi b/stubs/emlearn_neighbors.pyi index b817858d..7225d8f2 100644 --- a/stubs/emlearn_neighbors.pyi +++ b/stubs/emlearn_neighbors.pyi @@ -1,6 +1,5 @@ # Stub file (PEP 484) with API definitions and documentation for native module -# Is called .py because Sphinx autodoc currently does not support .pyi files """ K-nearest neighbors diff --git a/stubs/emlearn_trees.pyi b/stubs/emlearn_trees.pyi index a9142772..bf29eb03 100644 --- a/stubs/emlearn_trees.pyi +++ b/stubs/emlearn_trees.pyi @@ -1,5 +1,4 @@ # Stub file (PEP 484) with API definitions and documentation for native module -# Is called .py because Sphinx autodoc currently does not support .pyi files """ Tree-based models (Random Forest et.c.) From 621aa74e071412ecadf74fd88fa7b6dece641c3a Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 19:57:59 +0200 Subject: [PATCH 2/8] make: Add target for static type checking --- Makefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 637bc439..3814580f 100644 --- a/Makefile +++ b/Makefile @@ -196,7 +196,7 @@ QEMU_ARCH ?= armv7emdp QEMU_FIRMWARE = $(QEMU_PORT_DIR)/build-$(QEMU_BOARD)/firmware.elf # Build firmware for QEMU -.PHONY: qemu_build +.PHONY: qemu_build check_types qemu_build: $(MAKE) -C $(QEMU_PORT_DIR) BOARD=$(QEMU_BOARD) MICROPY_HEAP_SIZE=1024000 @@ -207,3 +207,12 @@ check_qemu: $(QEMU_FIRMWARE) python3 $(abspath tools/run_qemu_tests.py) --board $(QEMU_BOARD) --arch $(QEMU_ARCH) --abi-version $(MPY_ABI_VERSION) --mount $(abspath .) +# Type-check examples/ and tests/ against stubs/ with mypy. +# Uses --follow-imports=skip to skip imports of third-party packages not +# installed. +# Excludes subdirs that have duplicate module names or 3rd-party deps. +check_types: + MYPYPATH=./stubs python3 -m mypy \ + --follow-imports=skip \ + tests/ + From f9f8501a4671c4150f7149690d18b9f5e1fd7549 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 20:14:07 +0200 Subject: [PATCH 3/8] stubs: Add missing definitions and symlink variants --- stubs/emlearn_cnn_fp32.pyi | 1 + stubs/emlearn_cnn_int8.pyi | 1 + stubs/emlearn_extratrees.pyi | 126 ++++++++++++++++++++++++++ stubs/emlearn_iir_q15.pyi | 1 + stubs/emlearn_kmeans.pyi | 51 +++++++++++ stubs/emlearn_logreg.pyi | 165 +++++++++++++++++++++++++++++++++++ stubs/emlearn_plsr.pyi | 114 ++++++++++++++++++++++++ 7 files changed, 459 insertions(+) create mode 120000 stubs/emlearn_cnn_fp32.pyi create mode 120000 stubs/emlearn_cnn_int8.pyi create mode 100644 stubs/emlearn_extratrees.pyi create mode 120000 stubs/emlearn_iir_q15.pyi create mode 100644 stubs/emlearn_kmeans.pyi create mode 100644 stubs/emlearn_logreg.pyi create mode 100644 stubs/emlearn_plsr.pyi diff --git a/stubs/emlearn_cnn_fp32.pyi b/stubs/emlearn_cnn_fp32.pyi new file mode 120000 index 00000000..c33a7a87 --- /dev/null +++ b/stubs/emlearn_cnn_fp32.pyi @@ -0,0 +1 @@ +emlearn_cnn.pyi \ No newline at end of file diff --git a/stubs/emlearn_cnn_int8.pyi b/stubs/emlearn_cnn_int8.pyi new file mode 120000 index 00000000..c33a7a87 --- /dev/null +++ b/stubs/emlearn_cnn_int8.pyi @@ -0,0 +1 @@ +emlearn_cnn.pyi \ No newline at end of file diff --git a/stubs/emlearn_extratrees.pyi b/stubs/emlearn_extratrees.pyi new file mode 100644 index 00000000..49475f5a --- /dev/null +++ b/stubs/emlearn_extratrees.pyi @@ -0,0 +1,126 @@ +# Stub file (PEP 484) with API definitions and documentation for native module + +""" +Extra Trees (Extremely Randomized Trees) classification. + +Tree-based ensemble classifier with randomized splits. +""" + +import array +import typing +from typing import Iterator + + +class Model(): + """An ExtraTrees ensemble model + + Note: Use emlearn_extratrees.new to construct an instance + """ + def train(self, X : array.array, y : array.array) -> None: + """ + Train the model on the given data. + + :param X: Training features, int16 array of n_samples * n_features + :param y: Training labels, int16 array of n_samples + """ + pass + + def train_init(self, X : array.array, y : array.array) -> None: + """ + Initialize step-by-step training. + + :param X: Training features, int16 array of n_samples * n_features + :param y: Training labels, int16 array of n_samples + """ + pass + + def train_step(self) -> int: + """ + Process one node of step-by-step training. + + :return: 1 if training is complete, 0 if more steps needed + """ + pass + + def predict(self, features : array.array, probabilities : array.array) -> int: + """ + Make a prediction and fill the probabilities buffer. + + :param features: Input features, int16 array of n_features + :param probabilities: Output buffer, float32 array of n_classes (modified in-place) + :return: Predicted class index + """ + pass + + def get_n_features(self) -> int: + """ + Get the number of features. + """ + pass + + def get_n_classes(self) -> int: + """ + Get the number of classes. + """ + pass + + def get_n_trees(self) -> int: + """ + Get the number of trees in the ensemble. + """ + pass + + def get_n_nodes_used(self) -> int: + """ + Get the number of nodes currently used in the model. + """ + pass + + def get_n_trees_trained(self) -> int: + """ + Get the number of trees trained so far. + """ + pass + + def __del__(self) -> None: + pass + + +def new(n_features : int, n_classes : int, + *, n_trees : int = ..., max_depth : int = ..., + min_samples_leaf : int = ..., n_thresholds : int = ..., + subsample_ratio : float = ..., feature_subsample_ratio : float = ..., + max_nodes : int = ..., max_samples : int = ..., + rng_seed : int = ..., use_global_feature_range : bool = ...) -> Model: + """ + Construct a new ExtraTrees model. + + :param n_features: Number of input features + :param n_classes: Number of output classes + :param n_trees: Number of trees in the ensemble + :param max_depth: Maximum tree depth + :param min_samples_leaf: Minimum samples at a leaf node + :param n_thresholds: Random thresholds drawn per feature split + :param subsample_ratio: Fraction of samples used per tree (0.0-1.0) + :param feature_subsample_ratio: Fraction of features considered per split + :param max_nodes: Maximum pre-allocated nodes + :param max_samples: Maximum pre-allocated samples + :param rng_seed: Random number generator seed + :param use_global_feature_range: Use global feature range + """ + pass + + +def train_steps(model : Model, X : array.array, y : array.array) -> Iterator[int]: + """ + Generator for step-by-step training. + + Yields the number of trees trained so far after each step. + Returns when training is complete. + + :param model: ExtraTrees model instance + :param X: Training features, int16 array of n_samples * n_features + :param y: Training labels, int16 array of n_samples + :return: Iterator yielding trees_trained count + """ + pass diff --git a/stubs/emlearn_iir_q15.pyi b/stubs/emlearn_iir_q15.pyi new file mode 120000 index 00000000..a80335a7 --- /dev/null +++ b/stubs/emlearn_iir_q15.pyi @@ -0,0 +1 @@ +emlearn_iir.pyi \ No newline at end of file diff --git a/stubs/emlearn_kmeans.pyi b/stubs/emlearn_kmeans.pyi new file mode 100644 index 00000000..2a694fb2 --- /dev/null +++ b/stubs/emlearn_kmeans.pyi @@ -0,0 +1,51 @@ +# Stub file (PEP 484) with API definitions and documentation for native module + +""" +K-Means clustering with C-accelerated distance computation. +""" + +import array +import typing +from typing import Iterator + + +def euclidean_argmin(vectors : array.array, point : array.array) -> typing.Tuple[int, int]: + """ + Find the closest centroid/vector to a given point. + + :param vectors: All vectors concatenated, uint8 array of n_vectors * n_channels + :param point: Query point, uint8 array of n_channels + :return: Tuple of (closest_vector_index, squared_distance) + """ + pass + + +def cluster_iter(values : array.array, centroids : array.array, + assignments : array.array, features : int, + max_iter : int = ..., stop_changes : int = ...) -> Iterator[int]: + """ + Perform K-Means clustering with iteration yielding. + + :param values: Input data, uint8 array of n_samples * features + :param centroids: Initial centroids, uint8 array of n_clusters * features (modified in-place) + :param assignments: Output assignments, uint8 array of n_samples (modified in-place) + :param features: Number of features + :param max_iter: Maximum number of iterations + :param stop_changes: Stop if changes in assignments drop below this count + :return: Iterator yielding number of assignment changes per iteration + """ + pass + + +def cluster(values : array.array, centroids : array.array, + features : int, **kwargs) -> array.array: + """ + Run K-Means clustering and return sample assignments. + + :param values: Input data, uint8 array of n_samples * features + :param centroids: Initial centroids, uint8 array of n_clusters * features + :param features: Number of features + :param kwargs: Additional arguments (max_iter, stop_changes) + :return: Array of cluster assignments for each sample + """ + pass diff --git a/stubs/emlearn_logreg.pyi b/stubs/emlearn_logreg.pyi new file mode 100644 index 00000000..c86bc3bb --- /dev/null +++ b/stubs/emlearn_logreg.pyi @@ -0,0 +1,165 @@ +# Stub file (PEP 484) with API definitions and documentation for native module + +""" +Logistic Regression (binary and multiclass). + +For more complicated training needs, use the `train` or `train_batches` helper functions. +""" + +import array +import typing + + +class Model(): + """A logistic regression model + + Note: Use emlearn_logreg.new to construct an instance + """ + def predict(self, features : array.array, probs : array.array, logits : array.array) -> int: + """ + Run prediction and return the predicted class index. + + :param features: Input features, float32 array of n_features + :param probs: Output buffer for probabilities, float32 array of n_classes (modified in-place) + :param logits: Output buffer for logits, float32 array of n_classes (modified in-place) + :return: Index of the predicted class + """ + pass + + def step(self, X : array.array, y : array.array, + logits : array.array, probs : array.array, + bias_grads : array.array) -> None: + """ + Perform a single training iteration. + + :param X: Batch features, float32 array of n_samples * n_features + :param y: Batch targets (one-hot), float32 array of n_samples * n_classes + :param logits: Workspace buffer, float32 array of n_classes + :param probs: Workspace buffer, float32 array of n_classes + :param bias_grads: Workspace buffer, float32 array of n_classes + """ + pass + + def get_weights(self, out : array.array) -> None: + """ + Copy the model weights into an output buffer. + + :param out: Float32 buffer of n_features * n_classes (modified in-place) + """ + pass + + def set_weights(self, weights : array.array) -> None: + """ + Set the model weights from a buffer. + + :param weights: Float32 array of n_features * n_classes + """ + pass + + def get_bias(self, out : array.array) -> None: + """ + Copy the model biases into an output buffer. + + :param out: Float32 buffer of n_classes (modified in-place) + """ + pass + + def set_bias(self, bias : array.array) -> None: + """ + Set the model biases. + + :param bias: Float32 array of n_classes + """ + pass + + def get_n_features(self) -> int: + """ + Get the number of features. + """ + pass + + def get_n_classes(self) -> int: + """ + Get the number of classes. + """ + pass + + def score_logloss(self, X : array.array, y : array.array, + logits : array.array, probs : array.array) -> float: + """ + Compute the log-loss on a dataset. + + :param X: Features, float32 array of n_samples * n_features + :param y: Targets (one-hot), float32 array of n_samples * n_classes + :param logits: Workspace buffer, float32 array of n_classes + :param probs: Workspace buffer, float32 array of n_classes + :return: The log-loss value + """ + pass + + def __del__(self) -> None: + pass + + +def new(n_features : int, n_classes : int, + learning_rate : float, lambda_l2 : float, lambda_l1 : float) -> Model: + """ + Construct a new logistic regression model. + + :param n_features: Number of input features + :param n_classes: Number of output classes + :param learning_rate: Learning rate for gradient descent + :param lambda_l2: L2 regularization strength + :param lambda_l1: L1 regularization strength + """ + pass + + +def train(model : Model, X_train : array.array, y_train : array.array, + max_iterations : int = ..., + tolerance : float = ..., + check_interval : int = ..., + divergence_factor : float = ..., + score_limit : typing.Optional[float] = ..., + verbose : int = ...) -> typing.Tuple[int, float]: + """ + Full-dataset training loop for logistic regression. + + :param model: Logistic regression model instance + :param X_train: Training features, float32 array of n_samples * n_features + :param y_train: Training targets (one-hot), float32 array of n_samples * n_classes + :param max_iterations: Maximum number of training steps + :param tolerance: Convergence tolerance + :param check_interval: Check convergence every N iterations + :param divergence_factor: Divergence detection factor + :param score_limit: Stop training if score reaches this value + :param verbose: Verbosity level + :return: Tuple of (iterations_completed, final_loss) + """ + pass + + +def train_batches(model : Model, + batch_iter_factory : typing.Callable[[], typing.Iterator[typing.Tuple[array.array, array.array]]], + max_iterations : int = ..., + tolerance : float = ..., + check_interval : int = ..., + divergence_factor : float = ..., + score_limit : typing.Optional[float] = ..., + verbose : int = ..., + score_batches : typing.Optional[typing.Callable[[Model], float]] = ...) -> typing.Tuple[int, float]: + """ + Train logistic regression model using externally provided batches. + + :param model: Logistic regression model instance + :param batch_iter_factory: Callable returning a fresh iterator over (X_batch, y_batch) tuples + :param max_iterations: Maximum number of training epochs + :param tolerance: Convergence tolerance + :param check_interval: Check convergence every N epochs + :param divergence_factor: Divergence detection factor + :param score_limit: Stop training if score reaches this value + :param verbose: Verbosity level + :param score_batches: Optional callable computing score from the model + :return: Tuple of (iterations_completed, final_loss) + """ + pass diff --git a/stubs/emlearn_plsr.pyi b/stubs/emlearn_plsr.pyi new file mode 100644 index 00000000..241770e1 --- /dev/null +++ b/stubs/emlearn_plsr.pyi @@ -0,0 +1,114 @@ +# Stub file (PEP 484) with API definitions and documentation for native module + +""" +Partial Least Squares Regression (PLSR) + +Implemented using *eml_plsr* from the emlearn C library (https://github.com/emlearn/emlearn). +""" + +import array +import typing + + +class Model(): + """A PLSR model + + Note: Use emlearn_plsr.new to construct an instance + """ + def fit_start(self, X : array.array, y : array.array) -> None: + """ + Start iterative fitting of the model. + + :param X: Training input data, float32 array of n_samples * n_features + :param y: Training target data, float32 array of n_samples + """ + pass + + def step(self, tolerance : float = ...) -> None: + """ + Perform one NIPALS iteration step for the current component. + + :param tolerance: Convergence tolerance (optional) + """ + pass + + def finalize_component(self) -> None: + """ + Finalize the current component and prepare for the next one. + """ + pass + + def is_converged(self) -> bool: + """ + Check if the current component has converged. + """ + pass + + def is_complete(self) -> bool: + """ + Check if all components have been trained. + """ + pass + + def predict(self, x : array.array) -> float: + """ + Predict the target value for a single sample. + + :param x: Input features, float32 array of n_features + :return: Predicted target value + """ + pass + + def get_convergence_metric(self) -> float: + """ + Get the convergence metric for the current component. + """ + pass + + def set_auto_center(self, value : bool) -> None: + """ + Enable or disable automatic centering of data during fitting. + + :param value: Whether to auto-center + """ + pass + + def get_auto_center(self) -> bool: + """ + Get the auto-centering flag. + """ + pass + + def __del__(self) -> None: + pass + + +def new(n_samples : int, n_features : int, n_components : int) -> Model: + """ + Construct a new PLSR model. + + :param n_samples: Number of training samples + :param n_features: Number of input features + :param n_components: Number of PLS components + """ + pass + + +def fit(model : Model, X_train : array.array, y_train : array.array, + max_iterations : int = ..., + tolerance : float = ..., + check_interval : int = ..., + verbose : int = ...) -> typing.Tuple[int, float]: + """ + Train the PLSR model using a NIPALS iterative fitting loop. + + :param model: PLSR model instance + :param X_train: Training input data, float32 array of n_samples * n_features + :param y_train: Training target data, float32 array of n_samples + :param max_iterations: Maximum iterations per component + :param tolerance: Convergence tolerance + :param check_interval: Check convergence every N iterations + :param verbose: Verbosity level + :return: Tuple of (total_iterations, final_convergence_metric) + """ + pass From e16df8d5cc22a3d0fcce008b67aad7d4c99e0ecd Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 20:20:03 +0200 Subject: [PATCH 4/8] mypy: Skip tests/tools --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 3814580f..d595b8f7 100644 --- a/Makefile +++ b/Makefile @@ -214,5 +214,6 @@ check_qemu: $(QEMU_FIRMWARE) check_types: MYPYPATH=./stubs python3 -m mypy \ --follow-imports=skip \ + --exclude tests/tools/ \ tests/ From 6c921afcb9051080446637dda5b2f3c47b1feab3 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 20:20:20 +0200 Subject: [PATCH 5/8] requirements: Install mypy --- requirements.dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.dev.txt b/requirements.dev.txt index e36e3899..f11ec80c 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -5,3 +5,4 @@ sphinx_rtd_theme>=0.5.2 sphinx-gallery>=0.10.1 sphinx-autodoc-typehints>=3.0.1 myst_parser>=4.0.0 +mypy>=2.0.0 From 5bcb68bb87e7228d0275bc0578a1d15467bd4101 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 20:20:36 +0200 Subject: [PATCH 6/8] tests: Ignore print_exception() Exists in MicroPython, but not in CPython --- tests/test_extratrees.py | 2 +- tests/test_extratrees_xor.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_extratrees.py b/tests/test_extratrees.py index 14e089d6..a994f293 100644 --- a/tests/test_extratrees.py +++ b/tests/test_extratrees.py @@ -287,4 +287,4 @@ def test_train_step_same_as_train(): except Exception as e: print("Error during debugging: {}".format(e)) import sys - sys.print_exception(e) + sys.print_exception(e) # type: ignore[attr-defined] diff --git a/tests/test_extratrees_xor.py b/tests/test_extratrees_xor.py index 94f14f2f..d868f0a4 100644 --- a/tests/test_extratrees_xor.py +++ b/tests/test_extratrees_xor.py @@ -226,6 +226,6 @@ def test_xor_different_values(): except Exception as e: print(f"❌ Error: {e}") import sys - sys.print_exception(e) + sys.print_exception(e) # type: ignore[attr-defined] print("\n" + "="*60) From 6e9be36a3c26a8508762aca88f441b3ec5333905 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 20:25:24 +0200 Subject: [PATCH 7/8] CI: Add job to run static type checking --- .github/workflows/build.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 82e84e5b..9532a9d2 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -301,3 +301,18 @@ jobs: READTHEDOCS: 'True' run: | make html + + check-types: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Install Python dependencies + run: | + pip install -r requirements.txt -r requirements.dev.txt + - name: Run type checks + run: make check_types From caeab8d411b1165b1ba5b4dc59ed3d1bf15d1aae Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sun, 24 May 2026 20:34:32 +0200 Subject: [PATCH 8/8] docs: Add missing modules to API reference --- docs/api_reference.rst | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/api_reference.rst b/docs/api_reference.rst index c3e1240b..f1b446e3 100644 --- a/docs/api_reference.rst +++ b/docs/api_reference.rst @@ -18,7 +18,7 @@ API reference .. _emlearn_trees: -emlearn_trees - Decision tree ensembles +emlearn_trees - Decision tree ensemble inference ---------------------------------------------------- .. autoapimodule:: emlearn_trees @@ -31,8 +31,27 @@ emlearn_linreg - Linear regression .. autoapimodule:: emlearn_linreg :members: +.. _emlearn_linreg: +emlearn_logreg - Logistic regression classification +---------------------------------------------------- + +.. autoapimodule:: emlearn_logreg + :members: + +emlearn_extratrees - Learning decision tree ensembles +---------------------------------------------------- + +.. autoapimodule:: emlearn_extratrees + :members: + +emlearn_plsr - Partial Least Squares Regression (PLSR) +---------------------------------------------------- + +.. autoapimodule:: emlearn_plsr + :members: + .. _emlearn_cnn: -emlearn_cnn - Convolutional Neural Networks +emlearn_cnn - Convolutional Neural Networks inference ---------------------------------------------------------- .. autoapimodule:: emlearn_cnn