diff --git a/Makefile b/Makefile index d474465..0a4606d 100644 --- a/Makefile +++ b/Makefile @@ -10,49 +10,49 @@ MPY_DIR_ABS = $(abspath $(MPY_DIR)) MODULES_PATH = ./dist/$(ARCH)_$(MPY_ABI_VERSION) -$(MODULES_PATH)/emltrees.mpy: - make -C src/emltrees/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist +$(MODULES_PATH)/emlearn_trees.mpy: + make -C src/emlearn_trees/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist -$(MODULES_PATH)/emlneighbors.mpy: - make -C src/emlneighbors/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist +$(MODULES_PATH)/emlearn_neighbors.mpy: + make -C src/emlearn_neighbors/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist -$(MODULES_PATH)/emliir.mpy: - make -C src/emliir/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist +$(MODULES_PATH)/emlearn_iir.mpy: + make -C src/emlearn_iir/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist -$(MODULES_PATH)/emlfft.mpy: - make -C src/emlfft/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist +$(MODULES_PATH)/emlearn_fft.mpy: + make -C src/emlearn_fft/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist -$(MODULES_PATH)/tinymaix_cnn.mpy: +$(MODULES_PATH)/emlearn_cnn.mpy: make -C src/tinymaix_cnn/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist -$(MODULES_PATH)/emlkmeans.mpy: - make -C src/emlkmeans/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist +$(MODULES_PATH)/emlearn_kmeans.mpy: + make -C src/emlearn_kmeans/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist -$(MODULES_PATH)/eml_iir_q15.mpy: - make -C src/eml_iir_q15/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist +$(MODULES_PATH)/emlearn_iir_q15.mpy: + make -C src/emlearn_iir_q15/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist $(MODULES_PATH)/emlearn_arrayutils.mpy: make -C src/emlearn_arrayutils/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean dist -emltrees.results: $(MODULES_PATH)/emltrees.mpy +emlearn_trees.results: $(MODULES_PATH)/emlearn_trees.mpy MICROPYPATH=$(MODULES_PATH) $(MICROPYTHON_BIN) tests/test_trees.py -emlneighbors.results: $(MODULES_PATH)/emlneighbors.mpy +emlearn_neighbors.results: $(MODULES_PATH)/emlearn_neighbors.mpy MICROPYPATH=$(MODULES_PATH) $(MICROPYTHON_BIN) tests/test_neighbors.py -emliir.results: $(MODULES_PATH)/emliir.mpy +emlearn_iir.results: $(MODULES_PATH)/emlearn_iir.mpy MICROPYPATH=$(MODULES_PATH) $(MICROPYTHON_BIN) tests/test_iir.py -emlfft.results: $(MODULES_PATH)/emlfft.mpy +emlearn_fft.results: $(MODULES_PATH)/emlearn_fft.mpy MICROPYPATH=$(MODULES_PATH) $(MICROPYTHON_BIN) tests/test_fft.py -tinymaix_cnn.results: $(MODULES_PATH)/tinymaix_cnn.mpy +emlearn_cnn.results: $(MODULES_PATH)/emlearn_cnn.mpy MICROPYPATH=$(MODULES_PATH) $(MICROPYTHON_BIN) tests/test_cnn.py -emlkmeans.results: $(MODULES_PATH)/emlkmeans.mpy +emlearn_kmeans.results: $(MODULES_PATH)/emlearn_kmeans.mpy MICROPYPATH=$(MODULES_PATH) $(MICROPYTHON_BIN) tests/test_kmeans.py -eml_iir_q15.results: $(MODULES_PATH)/eml_iir_q15.mpy +emlearn_iir_q15.results: $(MODULES_PATH)/emlearn_iir_q15.mpy MICROPYPATH=$(MODULES_PATH) $(MICROPYTHON_BIN) tests/test_iir_q15.py emlearn_arrayutils.results: $(MODULES_PATH)/emlearn_arrayutils.mpy @@ -61,9 +61,9 @@ emlearn_arrayutils.results: $(MODULES_PATH)/emlearn_arrayutils.mpy .PHONY: clean clean: - make -C src/emltrees/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean - make -C src/emlneighbors/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean - make -C src/emliir/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean + make -C src/emlearn_trees/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean + make -C src/emlearn_neighbors/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean + make -C src/emlearn_iir/ ARCH=$(ARCH) MPY_DIR=$(MPY_DIR_ABS) V=1 clean rm -rf ./dist RELEASE_NAME = emlearn-micropython-$(VERSION) @@ -74,8 +74,8 @@ release: zip -r $(RELEASE_NAME).zip $(RELEASE_NAME) #cp $(RELEASE_NAME).zip emlearn-micropython-latest.zip -check: emltrees.results emlneighbors.results emliir.results eml_iir_q15.results emlfft.results emlkmeans.results emlearn_arrayutils.results tinymaix_cnn.results +check: emlearn_trees.results emlearn_neighbors.results emlearn_iir.results emlearn_iir_q15.results emlearn_fft.results emlearn_kmeans.results emlearn_arrayutils.results emlearn_cnn.results -dist: $(MODULES_PATH)/emltrees.mpy $(MODULES_PATH)/emlneighbors.mpy $(MODULES_PATH)/emliir.mpy $(MODULES_PATH)/eml_iir_q15.mpy $(MODULES_PATH)/emlfft.mpy $(MODULES_PATH)/emlkmeans.mpy $(MODULES_PATH)/emlearn_arrayutils.mpy $(MODULES_PATH)/tinymaix_cnn.mpy +dist: $(MODULES_PATH)/emlearn_trees.mpy $(MODULES_PATH)/emlearn_neighbors.mpy $(MODULES_PATH)/emlearn_iir.mpy $(MODULES_PATH)/emlearn_iir_q15.mpy $(MODULES_PATH)/emlearn_fft.mpy $(MODULES_PATH)/emlearn_kmeans.mpy $(MODULES_PATH)/emlearn_arrayutils.mpy $(MODULES_PATH)/emlearn_cnn.mpy diff --git a/README.md b/README.md index d600875..fa95479 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,21 @@ Download the repository with examples etc git clone https://github.com/emlearn/emlearn-micropython ``` -## Installing from a release +## Usage + +Start with the instructions in [XOR example](./examples/xor_trees/). + #### Find architecture and .mpy version +The correct .mpy files to use depend on the CPU architecture of your microcontroller, +as well as the MicroPython version. + +| MicroPython version | .mpy version | +|---------------------| ------------- | +| 1.23.x | 6.3 | + + Identify which CPU architecture your device uses. You need to specify `ARCH` to install the correct module version. @@ -79,43 +90,6 @@ Information is also available in the official documentation: [MicroPython: .mpy files](https://docs.micropython.org/en/latest/reference/mpyfiles.html#versioning-and-compatibility-of-mpy-files) -#### Download release files - -Download from [releases](https://github.com/emlearn/emlearn-micropython/releases). - -#### Install on device - -Copy the .mpy file for the correct `ARCH` to your device. -``` -mpremote cp emltrees.mpy :emltrees.mpy -mpremote cp emlneighbors.mpy :emlneighbors.mpy -``` - -NOTE: If there is no ready-made build for your device/architecture, -then you will need to build the .mpy module yourself. - -## Usage - -NOTE: Make sure to install the module first (see above) - -Train a model with scikit-learn -``` -pip install emlearn scikit-learn -python examples/xor_trees/xor_train.py -``` - -Copy model file to device - -``` -mpremote cp xor_model.csv :xor_model.csv -``` - -Run program that uses the model - -``` -mpremote run examples/xor_run.py -``` - ## Benchmarks #### UCI handwriting digits @@ -157,7 +131,7 @@ make dist ARCH=armv6m MPY_DIR=../micropython Install it on device ``` -mpremote cp dist/armv6m*/emltrees.mpy :emltrees.mpy +mpremote cp dist/armv6m*/emlearn_trees.mpy :emlearn_trees.mpy ``` #### Run tests diff --git a/benchmarks/digits_trees/digits_run.py b/benchmarks/digits_trees/digits_run.py index c7decbb..4b6898f 100644 --- a/benchmarks/digits_trees/digits_run.py +++ b/benchmarks/digits_trees/digits_run.py @@ -6,15 +6,15 @@ from everywhere_digits import RandomForestClassifier import m2c_digits -import emltrees +import emlearn_trees def emlearn_create(): - model = emltrees.new(10, 1000, 10) + model = emlearn_trees.new(10, 1000, 10) # Load a CSV file with the model with open('eml_digits.csv', 'r') as f: - emltrees.load_model(model, f) + emlearn_trees.load_model(model, f) return model def argmax(l): diff --git a/benchmarks/fft/fft_benchmark.py b/benchmarks/fft/fft_benchmark.py index fb281e4..75dd439 100644 --- a/benchmarks/fft/fft_benchmark.py +++ b/benchmarks/fft/fft_benchmark.py @@ -16,9 +16,9 @@ except ImportError as e: print(e) -emlfft = None +emlearn_fft = None try: - import emlfft + import emlearn_fft pass except ImportError as e: print(e) @@ -65,13 +65,13 @@ def run_one(real, imag, n, repeat=10): d = ((time.ticks_diff(time.ticks_us(), start)) / repeat) / 1000.0 # ms print('ulab', n, d) - # FIXME: this causes MicroPython to crash inside emlfft on ESP32 + # FIXME: this causes MicroPython to crash inside emlearn_fft on ESP32 #gc.collect() # emlearn if emlearn: - fft2 = emlfft.FFT(n) - emlfft.fill(fft2, n) + fft2 = emlearn_fft.FFT(n) + emlearn_fft.fill(fft2, n) gc.collect() start = time.ticks_us() diff --git a/benchmarks/fft/fft_benchmark.sh b/benchmarks/fft/fft_benchmark.sh index 4cd65a8..879e5c4 100644 --- a/benchmarks/fft/fft_benchmark.sh +++ b/benchmarks/fft/fft_benchmark.sh @@ -1,9 +1,9 @@ # NOTE: MicroPython must be flashed before-hand -# and emlfft.mpy built +# and emlearn_fft.mpy built MPREMOTE='mpremote' -${MPREMOTE} cp src/emlfft/emlfft.mpy : +${MPREMOTE} cp src/emlearn_fft/emlearn_fft.mpy : ${MPREMOTE} cp benchmarks/fft/fft_python.py : ${MPREMOTE} run benchmarks/fft/fft_benchmark.py diff --git a/benchmarks/iir/iir_benchmark.py b/benchmarks/iir/iir_benchmark.py index 575b04a..8048ccf 100644 --- a/benchmarks/iir/iir_benchmark.py +++ b/benchmarks/iir/iir_benchmark.py @@ -14,9 +14,9 @@ print(e) pass -emliir = None +emlearn_iir = None try: - import emliir + import emlearn_iir except ImportError as e: print(e) pass @@ -70,9 +70,9 @@ def main(): print('ulab', t) # emlearn - if emliir: + if emlearn_iir: start = time.ticks_us() - iir = emliir.new(coeff) + iir = emlearn_iir.new(coeff) for r in range(repeats): iir.run(a) t = (time.ticks_diff(time.ticks_us(), start) / repeats ) / 1000.0 # ms diff --git a/benchmarks/iir/iir_run.py b/benchmarks/iir/iir_run.py index 4c5e489..9c9e4a7 100644 --- a/benchmarks/iir/iir_run.py +++ b/benchmarks/iir/iir_run.py @@ -27,11 +27,11 @@ def iir_process_file(inp, out, filters, chunksize): if len(reader.shape) != 1: raise ValueError("Input must be 1d") if reader.typecode == 'f': - import emliir - filter = emliir.new(coefficients) + import emlearn_iir + filter = emlearn_iir.new(coefficients) elif reader.typecode == 'h': - import eml_iir_q15 - filter = eml_iir_q15.new(coefficients) + import emlearn_iir_q15 + filter = emlearn_iir_q15.new(coefficients) else: raise ValueError("Input must either be float32/f or int16/h") diff --git a/doc/TODO.md b/doc/TODO.md index 57f9b16..d32258a 100644 --- a/doc/TODO.md +++ b/doc/TODO.md @@ -3,7 +3,8 @@ # User journey - Level 0a. Run a pretrained example/demo in the browser -- Level 0b. Run a pretrained example/demo on a board +- Level 0b. Run a pretrained example/demo on PC/host +- Level 0c. Run a pretrained example/demo on a board - Level 1. Train custom model on-device - Level 2. Collect a dataset, do training on PC, deploy back to microcontroller - Level 3. Bake the custom model into the firmware @@ -20,33 +21,21 @@ sequence. On-device training demo -- Record piezo data with ADC. 100 Hz? -Typical taps. Slower pushes. Handling noises. -- Setup event detection for piezo. -In its own module. -Threshold on delta and level? -- Create emliir module, use for piezo detection +- Use accelerometer instead of piezo. On M5StickC, for example +- Compute impulsive-ness feature. Magnitude, RMS, exponential smooth, then Delta * times level ? +- Alternative: Use IIR for knock detection - Maybe blink during unlocked state - Add a blink to each event. For user feedback - Make demo video +- Add some documentation / README - Make state diagram - Make timing diagram. Highlight distances/features -- Add some documentation / README - -Learnings. - -- Putting piezo on small thin plate worked well. -On table not working, no response. -Hitting direct not so good either, rise of finger causes change. Double-trigger. Also tricky to hit in right place. -- LEDs as protection diodes worked well. Both red and green can be used. Lights up on direct hits, if placed by piezo. -- Analog RC filter is beneficial for piezo connections. Using 10k+100nF, has 160 Hz cutoff. Should maybe move it to 80Hz? Since only sampling at 100 Hz. -- Only direct hits can reach trigger levels on 3.3V I/O. Need ADC for other cases. But am seing some 100mV when placed on small plate -Examples +#### Examples - Add a novelty detection example? -Benchmarks +#### Benchmarks - Add FLASH and RAM usage - Test gzip compression of .csv model for trees @@ -56,3 +45,5 @@ Benchmarks In-browser demo - Test MicroPython build for WASM/browser +- Test getting audio input into MicroPython Webassembly +- Test getting IMU data (ie on phone), in browser diff --git a/doc/micropython-tinyml-status.md b/doc/micropython-tinyml-status.md index 5d58aa8..06e5d42 100644 --- a/doc/micropython-tinyml-status.md +++ b/doc/micropython-tinyml-status.md @@ -167,14 +167,14 @@ FIR filters. IIR filters. `scipy.signal.sosfilt` available in [ulab](https://github.com/v923z/micropython-ulab). -`emliir` available in [emlearn-micropython](https://github.com/emlearn/emlearn-micropython). +`emlearn_iir` available in [emlearn-micropython](https://github.com/emlearn/emlearn-micropython). ### Fast Fourier Transform (FFT) Key part of computing frequency spectrum, or time-frequency representations (spectrogram). FFT. `numpy.fft.fft` available in [ulab](https://github.com/v923z/micropython-ulab). -`emlfft` available in [emlearn-micropython](https://github.com/emlearn/emlearn-micropython). +`emlearn_fft` available in [emlearn-micropython](https://github.com/emlearn/emlearn-micropython). DCT. Not available? @@ -195,7 +195,7 @@ But over 10x slower than emlearn-micropython. ### K-nearest-neighbours -`emlneighbors` available in [emlearn-micropython](https://github.com/emlearn/emlearn-micropython). +`emlearn_neighbors` available in [emlearn-micropython](https://github.com/emlearn/emlearn-micropython). ### Convolutional Neural Network diff --git a/examples/color_quantize_kmeans/color_quantize.py b/examples/color_quantize_kmeans/color_quantize.py index 1389175..68344ad 100644 --- a/examples/color_quantize_kmeans/color_quantize.py +++ b/examples/color_quantize_kmeans/color_quantize.py @@ -9,7 +9,7 @@ import os import gc -import emlkmeans +import emlearn_kmeans @micropython.native def quantize_image(img, quant, palette, rowstride): @@ -55,7 +55,7 @@ def quantize_image_inner(img, quant, palette, rowstride : int, rows : int): #rgb = img[i:i+3] # find closest value in palette - palette_idx, distance = emlkmeans.euclidean_argmin(palette, rgb) + palette_idx, distance = emlearn_kmeans.euclidean_argmin(palette, rgb) #palette_idx, distance = 0, 0 o = row_offset + col @@ -103,7 +103,7 @@ def quantize_path(inp, outp, palette, n_samples=100): # Learn a palette start = time.ticks_us() - emlkmeans.cluster(samples, palette, features=3, max_iter=20) + emlearn_kmeans.cluster(samples, palette, features=3, max_iter=20) dur = (time.ticks_diff(time.ticks_us(), start) / 1000.0) print('cluster duration (ms)', dur) diff --git a/examples/mnist_cnn/README.md b/examples/mnist_cnn/README.md index a7a3f55..540ca28 100644 --- a/examples/mnist_cnn/README.md +++ b/examples/mnist_cnn/README.md @@ -30,7 +30,7 @@ python mnist_train.py ## Running on host ```console -curl -o tinymaix_cnn.mpy https://github.com/emlearn/emlearn-micropython/raw/refs/heads/gh-pages/builds/master/x64_6.3/tinymaix_cnn.mpy +micropython -m mip install https://emlearn.github.io/emlearn-micropython/builds/master/x64_6.3/emlearn_cnn.mpy micropython mnist_cnn_run.py ``` @@ -43,11 +43,10 @@ Flash your device with a standard MicroPython firmware, from the MicroPython.org downloads page. ```console -curl -o device/tinymaix_cnn.mpy https://github.com/emlearn/emlearn-micropython/raw/refs/heads/gh-pages/builds/master/xtensawin_6.3/tinymaix_cnn.mpy +mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_cnn.mpy ``` ```console -mpremote cp device/tinymaix_cnn.mpy : mpremote cp mnist_cnn.tmdl : mpremote cp -r data/ : mpremote run mnist_cnn_run.py diff --git a/examples/mnist_cnn/mnist_cnn_run.py b/examples/mnist_cnn/mnist_cnn_run.py index 982fed3..b50d44e 100644 --- a/examples/mnist_cnn/mnist_cnn_run.py +++ b/examples/mnist_cnn/mnist_cnn_run.py @@ -1,6 +1,6 @@ import array -import tinymaix_cnn +import emlearn_cnn import time import gc @@ -26,7 +26,7 @@ def test_cnn_mnist(): model = None with open(MODEL, 'rb') as f: model_data = array.array('B', f.read()) - model = tinymaix_cnn.new(model_data) + model = emlearn_cnn.new(model_data) # run on some test data for class_no in range(0, 10): diff --git a/examples/sequence/sequence_lock.py b/examples/sequence/sequence_lock.py index 719ed33..5409e47 100644 --- a/examples/sequence/sequence_lock.py +++ b/examples/sequence/sequence_lock.py @@ -1,7 +1,7 @@ import os import array -import emlneighbors +import emlearn_neighbors TRAINING_STATE = 'training' UNLOCKED_STATE = 'unlocked' @@ -193,9 +193,9 @@ def _reset_model(self): items = self.training_examples features = self.sequence_length-1 - self.model = emlneighbors.new(items, features, items) + self.model = emlearn_neighbors.new(items, features, items) - # XXX: could be dropped if emlneighbors allowed accessing n_items + # XXX: could be dropped if emlearn_neighbors allowed accessing n_items self.training_items = 0 def _get_distances(self, features): diff --git a/examples/soundlevel_iir/README.md b/examples/soundlevel_iir/README.md index 63ded20..c0a0495 100644 --- a/examples/soundlevel_iir/README.md +++ b/examples/soundlevel_iir/README.md @@ -25,7 +25,7 @@ sound level meter used for noise measurements: The following emlearn functionality are used in the implementation: -- `emliir`. IIR filters to implement the A weighting filter +- `emlearn_iir`. IIR filters to implement the A weighting filter - `emlearn_arrayutils.linear_map()`. To convert array values between `float` and `int16` @@ -83,7 +83,7 @@ pip install -r requirements.txt Install the emlearn modules ```console micropython -m mip install https://emlearn.github.io/emlearn-micropython/builds/master/x64_6.3/emlearn_arrayutils.mpy -micropython -m mip install https://emlearn.github.io/emlearn-micropython/builds/master/x64_6.3/emliir.mpy +micropython -m mip install https://emlearn.github.io/emlearn-micropython/builds/master/x64_6.3/emlearn_iir.mpy ``` Compute soundlevels for a file @@ -103,7 +103,7 @@ Ensure you have an I2S microphone, and that the pinout is correct in `soundlevel Install the emlearn modules *for your architecture*. ESP32=xtensawin ```console mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_arrayutils.mpy -mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emliir.mpy +mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_iir.mpy ``` Copy example code to the device @@ -191,7 +191,7 @@ WIFI_PASSWORD = 'MY WIFI PASSWORD' Install the emlearn modules *for your architecture*. ESP32=xtensawin ```console mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_arrayutils.mpy -mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emliir.mpy +mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_iir.mpy ``` Copy example to the device @@ -220,7 +220,7 @@ So the example can be adapted to other displays supported by that framework. Install the emlearn modules *for your architecture*. ESP32=xtensawin ```console mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_arrayutils.mpy -mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emliir.mpy +mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_iir.mpy ``` Install UI framework and screen driver diff --git a/examples/soundlevel_iir/soundlevel.py b/examples/soundlevel_iir/soundlevel.py index 6d93744..83b9122 100644 --- a/examples/soundlevel_iir/soundlevel.py +++ b/examples/soundlevel_iir/soundlevel.py @@ -4,24 +4,24 @@ import array from collections import deque -import emliir +import emlearn_iir from emlearn_arrayutils import linear_map -#import eml_iir_q15 +#import emlearn_iir_q15 #from iir_python import IIRFilter class IIRFilterEmlearn: def __init__(self, coefficients): c = array.array('f', coefficients) - self.iir = emliir.new(c) + self.iir = emlearn_iir.new(c) def process(self, samples): self.iir.run(samples) class IIRFilterEmlearnFixed: def __init__(self, coefficients): - c = eml_iir_q15.convert_coefficients(coefficients) - self.iir = eml_iir_q15.new(c) + c = emlearn_iir_q15.convert_coefficients(coefficients) + self.iir = emlearn_iir_q15.new(c) def process(self, samples): self.iir.run(samples) diff --git a/examples/xor_trees/README.md b/examples/xor_trees/README.md index 4586a4b..0305254 100644 --- a/examples/xor_trees/README.md +++ b/examples/xor_trees/README.md @@ -31,7 +31,8 @@ python xor_train.py ## Running on host ```console -curl -o emltrees.mpy https://github.com/emlearn/emlearn-micropython/raw/refs/heads/gh-pages/builds/master/x64_6.3/emltrees.mpy +micropython -m mip install https://emlearn.github.io/emlearn-micropython/builds/master/x64_6.3/emlearn_trees.mpy + micropython xor_run.py ``` @@ -43,9 +44,7 @@ This command is for ESP32 (xtensawin). For other hardware, replace the string. ```console -mkdir -p device -curl -o device/emltrees.mpy https://github.com/emlearn/emlearn-micropython/raw/refs/heads/gh-pages/builds/master/xtensawin_6.3/emltrees.mpy -mpremote cp emltrees.mpy : +mpremote mip install https://emlearn.github.io/emlearn-micropython/builds/master/xtensawin_6.3/emlearn_trees.mpy ``` ``` diff --git a/examples/xor_trees/xor_run.py b/examples/xor_trees/xor_run.py index 7d9b20e..5d220cf 100644 --- a/examples/xor_trees/xor_run.py +++ b/examples/xor_trees/xor_run.py @@ -1,13 +1,13 @@ # device/micropython code -import emltrees +import emlearn_trees import array -model = emltrees.new(5, 30, 2) +model = emlearn_trees.new(5, 30, 2) # Load a CSV file with the model with open('xor_model.csv', 'r') as f: - emltrees.load_model(model, f) + emlearn_trees.load_model(model, f) # run it max_val = (2**15-1) # 1.0 as int16 diff --git a/src/emlfft/Makefile b/src/emlearn_fft/Makefile similarity index 99% rename from src/emlfft/Makefile rename to src/emlearn_fft/Makefile index 6a827ea..ed494d1 100644 --- a/src/emlfft/Makefile +++ b/src/emlearn_fft/Makefile @@ -14,7 +14,7 @@ EMLEARN_DIR := $(shell python3 -c "import emlearn; print(emlearn.includedir)") DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION) # Name of module -MOD = emlfft +MOD = emlearn_fft # Source files (.c or .py) SRC = fft.c fft.py diff --git a/src/emlfft/fft.c b/src/emlearn_fft/fft.c similarity index 100% rename from src/emlfft/fft.c rename to src/emlearn_fft/fft.c diff --git a/src/emlfft/fft.py b/src/emlearn_fft/fft.py similarity index 100% rename from src/emlfft/fft.py rename to src/emlearn_fft/fft.py diff --git a/src/emliir/Makefile b/src/emlearn_iir/Makefile similarity index 98% rename from src/emliir/Makefile rename to src/emlearn_iir/Makefile index 1e4d1b4..96b57a6 100644 --- a/src/emliir/Makefile +++ b/src/emlearn_iir/Makefile @@ -14,7 +14,7 @@ EMLEARN_DIR := $(shell python3 -c "import emlearn; print(emlearn.includedir)") DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION) # Name of module -MOD = emliir +MOD = emlearn_iir # Source files (.c or .py) SRC = iir_filter.c diff --git a/src/emliir/iir_filter.c b/src/emlearn_iir/iir_filter.c similarity index 100% rename from src/emliir/iir_filter.c rename to src/emlearn_iir/iir_filter.c diff --git a/src/eml_iir_q15/Makefile b/src/emlearn_iir_q15/Makefile similarity index 99% rename from src/eml_iir_q15/Makefile rename to src/emlearn_iir_q15/Makefile index ea217ca..d4dd712 100644 --- a/src/eml_iir_q15/Makefile +++ b/src/emlearn_iir_q15/Makefile @@ -13,7 +13,7 @@ CMSIS_DSP_DIR := ../../dependencies/CMSIS-DSP DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION) # Name of module -MOD = eml_iir_q15 +MOD = emlearn_iir_q15 # Source files (.c or .py) SRC = iir_filter.c iir_filter.py diff --git a/src/eml_iir_q15/iir_filter.c b/src/emlearn_iir_q15/iir_filter.c similarity index 100% rename from src/eml_iir_q15/iir_filter.c rename to src/emlearn_iir_q15/iir_filter.c diff --git a/src/eml_iir_q15/iir_filter.py b/src/emlearn_iir_q15/iir_filter.py similarity index 89% rename from src/eml_iir_q15/iir_filter.py rename to src/emlearn_iir_q15/iir_filter.py index aa0da2b..95ec157 100644 --- a/src/eml_iir_q15/iir_filter.py +++ b/src/emlearn_iir_q15/iir_filter.py @@ -7,9 +7,9 @@ def convert_coefficients(c, scale=(2**13)-1): assert (len(c) % 6 == 0), len(c) n_stages = len(c) // 6 - # Transposed Direct Form II / sosfilt / emliir + # Transposed Direct Form II / sosfilt / emlearn_iir # [ b0, b1, b2, 1.0, -a1, -a2 ] - # Direct Form I / eml_iir_q15 + # Direct Form I / emlearn_iir_q15 # [ b0, 0, b1, b2, a1, a2 ] # NOTE: CMSIS-DSP “a” coefficients are negative compared to SciPy conventions diff --git a/src/emlkmeans/Makefile b/src/emlearn_kmeans/Makefile similarity index 98% rename from src/emlkmeans/Makefile rename to src/emlearn_kmeans/Makefile index 515d030..d50e56a 100644 --- a/src/emlkmeans/Makefile +++ b/src/emlearn_kmeans/Makefile @@ -10,7 +10,7 @@ MPY_ABI_VERSION := 6.3 DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION) # Name of module -MOD = emlkmeans +MOD = emlearn_kmeans # Source files (.c or .py) SRC = kmeans.c kmeans.py diff --git a/src/emlkmeans/kmeans.c b/src/emlearn_kmeans/kmeans.c similarity index 100% rename from src/emlkmeans/kmeans.c rename to src/emlearn_kmeans/kmeans.c diff --git a/src/emlkmeans/kmeans.py b/src/emlearn_kmeans/kmeans.py similarity index 100% rename from src/emlkmeans/kmeans.py rename to src/emlearn_kmeans/kmeans.py diff --git a/src/emlneighbors/Makefile b/src/emlearn_neighbors/Makefile similarity index 97% rename from src/emlneighbors/Makefile rename to src/emlearn_neighbors/Makefile index a1ec71e..cd12854 100644 --- a/src/emlneighbors/Makefile +++ b/src/emlearn_neighbors/Makefile @@ -14,7 +14,7 @@ DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION) # Name of module # NOTE: cannot contain _ - functions do not register on the module then? -MOD = emlneighbors +MOD = emlearn_neighbors # Source files (.c or .py) SRC = neighbors.c diff --git a/src/emlneighbors/neighbors.c b/src/emlearn_neighbors/neighbors.c similarity index 100% rename from src/emlneighbors/neighbors.c rename to src/emlearn_neighbors/neighbors.c diff --git a/src/emltrees/Makefile b/src/emlearn_trees/Makefile similarity index 98% rename from src/emltrees/Makefile rename to src/emlearn_trees/Makefile index 4da9469..d6111c2 100644 --- a/src/emltrees/Makefile +++ b/src/emlearn_trees/Makefile @@ -15,7 +15,7 @@ DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION) # Name of module # NOTE: cannot contain _ - functions do not register on the module then? -MOD = emltrees +MOD = emlearn_trees # Source files (.c or .py) SRC = trees.c trees.py diff --git a/src/emltrees/model.h b/src/emlearn_trees/model.h similarity index 100% rename from src/emltrees/model.h rename to src/emlearn_trees/model.h diff --git a/src/emltrees/trees.c b/src/emlearn_trees/trees.c similarity index 100% rename from src/emltrees/trees.c rename to src/emlearn_trees/trees.c diff --git a/src/emltrees/trees.py b/src/emlearn_trees/trees.py similarity index 100% rename from src/emltrees/trees.py rename to src/emlearn_trees/trees.py diff --git a/src/tinymaix_cnn/Makefile b/src/tinymaix_cnn/Makefile index 7cf60f8..d8fd5d2 100644 --- a/src/tinymaix_cnn/Makefile +++ b/src/tinymaix_cnn/Makefile @@ -13,7 +13,7 @@ TINYMAIX_DIR := ../../dependencies/TinyMaix DIST_DIR := ../../dist/$(ARCH)_$(MPY_ABI_VERSION) # Name of module -MOD = tinymaix_cnn +MOD = emlearn_cnn # Source files (.c or .py) SRC = mod_cnn.c diff --git a/tests/test_cnn.py b/tests/test_cnn.py index 805e5aa..1bf439e 100644 --- a/tests/test_cnn.py +++ b/tests/test_cnn.py @@ -1,6 +1,6 @@ import array -import tinymaix_cnn +import emlearn_cnn MNIST_MODEL = 'examples/mnist_cnn/mnist_cnn.tmdl' MNIST_DATA_DIR = 'examples/mnist_cnn/data/' @@ -10,7 +10,7 @@ def test_cnn_create(): model = None with open(MNIST_MODEL, 'rb') as f: model_data = array.array('B', f.read()) - model = tinymaix_cnn.new(model_data) + model = emlearn_cnn.new(model_data) # TODO: enable these checks #wrong_type = array.array('f', []) @@ -40,7 +40,7 @@ def test_cnn_mnist(): model = None with open(MNIST_MODEL, 'rb') as f: model_data = array.array('B', f.read()) - model = tinymaix_cnn.new(model_data) + model = emlearn_cnn.new(model_data) correct = 0 for class_no in range(0, 10): diff --git a/tests/test_fft.py b/tests/test_fft.py index db5f9e4..ba39807 100644 --- a/tests/test_fft.py +++ b/tests/test_fft.py @@ -1,5 +1,5 @@ -import emlfft +import emlearn_fft import array import gc @@ -14,7 +14,7 @@ def test_fft_del(): fft_length = 256 - model = emlfft.FFT(fft_length) + model = emlearn_fft.FFT(fft_length) after_new = gc.mem_alloc() added = after_new - before_new @@ -36,9 +36,9 @@ def test_fft_run(): fft_length = 128 in_real = array.array('f', (0.0 for _ in range(fft_length))) in_imag = array.array('f', (0.0 for _ in range(fft_length))) - model = emlfft.FFT(fft_length) + model = emlearn_fft.FFT(fft_length) - emlfft.fill(model, fft_length) + emlearn_fft.fill(model, fft_length) model.run(in_real, in_imag) # FIXME: use some reasonable input data and assert the output data diff --git a/tests/test_iir.py b/tests/test_iir.py index 2f932ff..b8f165e 100644 --- a/tests/test_iir.py +++ b/tests/test_iir.py @@ -1,5 +1,5 @@ -import emliir +import emlearn_iir import array import gc @@ -26,7 +26,7 @@ def test_iir_del(): -1.999111423794296, 0.9991118187443988 ]) - model = emliir.new(coefficients) + model = emlearn_iir.new(coefficients) after_new = gc.mem_alloc() added = after_new - before_new diff --git a/tests/test_iir_q15.py b/tests/test_iir_q15.py index 287a84e..43789cc 100644 --- a/tests/test_iir_q15.py +++ b/tests/test_iir_q15.py @@ -1,6 +1,6 @@ -import eml_iir_q15 +import emlearn_iir_q15 import array import gc @@ -23,7 +23,7 @@ def test_convert_coefficients(): inp = EXAMPLE_COEFFICIENTS - out = eml_iir_q15.convert_coefficients(inp) + out = emlearn_iir_q15.convert_coefficients(inp) def test_iir_del(): @@ -33,11 +33,11 @@ def test_iir_del(): gc.enable() gc.collect() - coefficients = eml_iir_q15.convert_coefficients(EXAMPLE_COEFFICIENTS) + coefficients = emlearn_iir_q15.convert_coefficients(EXAMPLE_COEFFICIENTS) before_new = gc.mem_alloc() - model = eml_iir_q15.new(coefficients) + model = emlearn_iir_q15.new(coefficients) after_new = gc.mem_alloc() added = after_new - before_new diff --git a/tests/test_kmeans.py b/tests/test_kmeans.py index 3301c79..3759ef2 100644 --- a/tests/test_kmeans.py +++ b/tests/test_kmeans.py @@ -1,5 +1,5 @@ -import emlkmeans +import emlearn_kmeans import array import gc @@ -42,7 +42,7 @@ def test_kmeans_two_clusters(): for typecode in ['bytearray', 'B']: dataset, centroids = make_two_cluster_data(typecode) - assignments = emlkmeans.cluster(dataset, centroids, features=n_features) + assignments = emlearn_kmeans.cluster(dataset, centroids, features=n_features) assert len(assignments) == len(dataset)/n_features assert list(assignments) == [0, 0, 1, 1], assignments @@ -57,7 +57,7 @@ def test_kmeans_many_features(): dataset = array.array(typecode, (0 for _ in range(n_features*n_samples)) ) centroids = array.array(typecode, (0 for _ in range(n_features*n_clusters)) ) - assignments = emlkmeans.cluster(dataset, centroids, features=n_features, max_iter=2) + assignments = emlearn_kmeans.cluster(dataset, centroids, features=n_features, max_iter=2) assert len(assignments) == len(dataset)/n_features assert min(assignments) >= 0 assert max(assignments) < n_clusters diff --git a/tests/test_neighbors.py b/tests/test_neighbors.py index b7802da..f89ef2a 100644 --- a/tests/test_neighbors.py +++ b/tests/test_neighbors.py @@ -1,5 +1,5 @@ -import emlneighbors +import emlearn_neighbors import array import gc @@ -12,7 +12,7 @@ def test_neighbors_del(): gc.enable() gc.collect() before_new = gc.mem_alloc() - model = emlneighbors.new(30, 5, 1) + model = emlearn_neighbors.new(30, 5, 1) after_new = gc.mem_alloc() added = after_new - before_new gc.collect() @@ -29,7 +29,7 @@ def test_neighbors_trivial(): n_features = 3 n_items = 100 k_neighbors = 2 - model = emlneighbors.new(n_items, n_features, k_neighbors) + model = emlearn_neighbors.new(n_items, n_features, k_neighbors) item = array.array('h', [0, 0, 0]) @@ -54,7 +54,7 @@ def test_neighbors_trivial(): def test_neighbors_get_results(): - model = emlneighbors.new(100, 3, 1) + model = emlearn_neighbors.new(100, 3, 1) data = [ (array.array('h', [-100, -100, -2]), 0), diff --git a/tests/test_trees.py b/tests/test_trees.py index d62eabe..cca418a 100644 --- a/tests/test_trees.py +++ b/tests/test_trees.py @@ -1,5 +1,5 @@ -import emltrees +import emlearn_trees import array import gc @@ -12,7 +12,7 @@ def test_trees_del(): gc.collect() before_new = gc.mem_alloc() - model = emltrees.new(5, 30, 4) + model = emlearn_trees.new(5, 30, 4) after_new = gc.mem_alloc() added = after_new - before_new @@ -29,11 +29,11 @@ def test_trees_xor(): Loading simple XOR model and predictions should give correct results """ - model = emltrees.new(5, 30, 4) + model = emlearn_trees.new(5, 30, 4) # Load a CSV file with the model with open('examples/xor_trees/xor_model.csv', 'r') as f: - emltrees.load_model(model, f) + emlearn_trees.load_model(model, f) # run it s = 32767 # max int16