Skip to content

Commit 22c7bd9

Browse files
committed
Add model deployment info.
1 parent fc3e65d commit 22c7bd9

File tree

1 file changed

+165
-2
lines changed

1 file changed

+165
-2
lines changed

content/pybytes/mlintegration/features.md

Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,172 @@ Select the devices and click on the **DEPLOY MODEL** button.
9090

9191
![Model Deployment](/gitbook/assets/pybytes/ml/deploy.png)
9292

93-
* Once you have the model deployed on the devices, it can be used for furthers applications like movement detection and so on.
93+
* Once the model is deployed on the device, it can be called from python code to classify new gestures using the data collected from the accelerometer sensor.
9494

95-
* This file is going to be used by the device firmware, and once generated it should not be changed by the user. Any changes can cause features to malfunction.
95+
* The path to the deployed model is: `/flash/model_definition.json`. This file is going to be used by the device firmware, and once generated it should not be changed by the user. Any changes can cause features to malfunction.
9696

97+
* The pycom module provides two functions for model interaction: `pycom.ml_new_model()` and `pycom.ml_run_model()`. Below is a very simple example:
98+
99+
```python
100+
import json
101+
import pycom
102+
103+
# A window which contains a gesture. Should be a list with 126 * 3 = 378 entries. This is because, in model_definition.json, the window_size_ms = 2000, sampling_frequency=62.5, so: 62.5*2 + 1 = 126 samples in a window.
104+
# The data is in the next format: acc_x, acc_y, acc_z, acc_x, ...
105+
# This is just an example. In a real application, this data should be collected from the accelerometer.
106+
data_l = []
107+
108+
# Read deployed model.
109+
with open('/flash/model_definition.json') as file:
110+
model_str = file.read()
111+
model_dict = json.loads(model_str)
112+
113+
# Read labels.
114+
for block in model_dict['model']['blocks']:
115+
if block['block_type'] == 'nn_block':
116+
output_labels = block['trained_nn_model']['label_to_id']
117+
118+
def new_model():
119+
"""Instantiate deployed model."""
120+
ret = pycom.ml_new_model(model_str)
121+
print('new_model status = {}'.format(ret))
122+
123+
def run_model():
124+
"""Run model to classify data."""
125+
result = pycom.ml_run_model(data_l)['NN']
126+
# Map probabilities to labels and print the result.
127+
for (label, index) in output_labels.items():
128+
print('{}: {:.2}%'.format(label, result[index] * 100))
129+
130+
new_model()
131+
run_model()
132+
```
133+
134+
* And an example in which data is real-time collected from the accelerometer:
135+
136+
```python
137+
import pycom
138+
import time
139+
import json
140+
from pysense import Pysense
141+
from LIS2HH12 import *
142+
import _thread
143+
144+
GRAVITATIONAL_ACC = 9.80665
145+
146+
with open('/flash/model_definition.json') as file:
147+
model_str = file.read()
148+
149+
done_acq = False
150+
data = []
151+
done_sig = False
152+
153+
py = Pysense()
154+
155+
li = LIS2HH12(py)
156+
li.set_odr(ODR_400_HZ)
157+
158+
def new_model():
159+
160+
print('Create new model.')
161+
162+
ret = pycom.ml_new_model(model_str)
163+
164+
print('ret = {}'.format(ret))
165+
166+
def run_model(data_l):
167+
168+
print('Run model.')
169+
170+
t0 = time.ticks_us()
171+
ret = pycom.ml_run_model(data_l)
172+
delta = time.ticks_us() - t0
173+
174+
print("time duration = {} ms".format(delta/1000))
175+
176+
return ret
177+
178+
def data_acq(window_size_ms, sampling_frequency, window_step_ms):
179+
global done_acq, data, done_sig
180+
181+
delta_t_us = int(1000000.0 / sampling_frequency)
182+
samples_num = 3 * int(window_size_ms * sampling_frequency / 1000)
183+
step_samples = 3 * int(window_step_ms * sampling_frequency / 1000)
184+
185+
print("Start acquisition data for %d msec, freq %d Hz, samples_num %d"%(window_size_ms, sampling_frequency, samples_num))
186+
187+
data_local = []
188+
index = 0
189+
done_acq = False
190+
191+
next_ts = time.ticks_us()
192+
while True:
193+
if done_sig:
194+
_thread.exit()
195+
# while next_ts - time.ticks_us() > 0:
196+
while time.ticks_diff(next_ts, time.ticks_us()) > 0:
197+
pass
198+
acc = li.acceleration()
199+
ts = next_ts
200+
data_local.append(acc[0] * GRAVITATIONAL_ACC)
201+
data_local.append(acc[1] * GRAVITATIONAL_ACC)
202+
data_local.append(acc[2] * GRAVITATIONAL_ACC)
203+
next_ts = ts + delta_t_us
204+
index += 3
205+
if index >= samples_num:
206+
# signal the main thread that we have a new window of data
207+
done_acq = True
208+
data = data_local[-samples_num:]
209+
# delete the first samples, that are not useful anymore
210+
index -= step_samples
211+
del data_local[:step_samples]
212+
213+
# parse the mode to obtain window sise and sampling frecquncy
214+
try:
215+
model_dict = json.loads(model_str)
216+
window_size_ms = float(model_dict['model']['blocks'][0]['window_size_ms'])
217+
sampling_frequency = float(model_dict['model']['blocks'][0]['sampling_frequency'])
218+
window_step_ms = float(model_dict['model']['blocks'][0]['window_step_ms'])
219+
output_labels = model_dict['model']['blocks'][2]['trained_nn_model']['label_to_id']
220+
minimum_confidence_rating = model_dict['model']['blocks'][2]['trained_nn_model']['minimum_confidence_rating']
221+
except:
222+
print("Model parsing failed")
223+
import sys
224+
sys.exit(0)
225+
226+
new_model()
227+
228+
_thread.start_new_thread(data_acq, (window_size_ms, sampling_frequency, window_step_ms))
229+
230+
print("Result labels: ", output_labels)
231+
232+
while True:
233+
234+
# wait for buffer of acceleration to be filled in the Thread
235+
while not done_acq:
236+
time.sleep(.2)
237+
done_acq = False
238+
# print("\nNew data:", len(data), data[:10])
239+
result = run_model(data)['NN']
240+
# print("Inference result:", result)
241+
activity = "None"
242+
activity_idx = -1
243+
if max(result) >= minimum_confidence_rating:
244+
activity_idx = result.index(max(result))
245+
246+
for (label, index) in output_labels.items():
247+
print('{}: {:.2}%'.format(label, result[index] * 100))
248+
# print('{}: {}'.format(label, index))
249+
if activity_idx == index:
250+
activity = label
251+
252+
print("Result activity: {}".format(activity))
253+
print("--------------------------------------------------")
254+
255+
done_sig = True
256+
time.sleep(1)
257+
print("Done")
258+
259+
```
97260

98261
[**Machine Learning Integration**](/pybytes/mlintegration)

0 commit comments

Comments
 (0)