From 9eb30387b52bd517bbf14c08f84f231876631b38 Mon Sep 17 00:00:00 2001 From: Agrimagsrl Date: Sun, 26 Jan 2020 11:21:49 +0100 Subject: [PATCH] first commit --- .gitignore | 5 +++++ MANIFEST | 3 +++ README.md | 32 ++++++++++++++++++++++++++++++++ dist/tinymlgen-0.1.tar.gz | Bin 0 -> 1418 bytes setup.py | 27 +++++++++++++++++++++++++++ tinymlgen/__init__.py | 1 + tinymlgen/tinymlgen.py | 35 +++++++++++++++++++++++++++++++++++ 7 files changed, 103 insertions(+) create mode 100644 .gitignore create mode 100644 MANIFEST create mode 100644 README.md create mode 100644 dist/tinymlgen-0.1.tar.gz create mode 100644 setup.py create mode 100644 tinymlgen/__init__.py create mode 100644 tinymlgen/tinymlgen.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c51d91e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +try.py +publish +venv +.idea +tinymlgen/__pycache__ \ No newline at end of file diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..6723bc9 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,3 @@ +# file GENERATED by distutils, do NOT edit +setup.py +tinymlgen/tinymlgen.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..477435e --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# TinyML gen + +This is a simple package to export a model trained in Tensorflow Lite +to a plain C array, ready to be used for inference on microcontrollers. + +### Install + +```shell script +pip install tinymlgen +``` + +### Use + +```python +from tinymlgen import port + +if __name__ == '__main__': + tf_model = create_tf_model() + c_code = port(tf_model) +``` + +### Configuration + +You can pass a few parameters to the `port` function: + + - `optimize (=True)`: apply optimizers to the exported model. + Can either be a list of optimizers or a boolean, in which case + `OPTIMIZE_FOR_SIZE` is applied + - `variable_name (='model_data')`: give the exported array a custom name + - `pretty_print (=False)`: print the array in a nicely formatted arrangement + + diff --git a/dist/tinymlgen-0.1.tar.gz b/dist/tinymlgen-0.1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c05ad85dc0725999ed35843699c3cd24f76b77fd GIT binary patch literal 1418 zcmV;51$Fu#iwFqMYb{;^|72-%bT4#iZh38NXJu|JFfK7JbYXG;?N|SA+C~)TXa5y9 zRjF+i9Gd`|!7cI^o$ zO$6o$)e;)Ah(j#Lghop9cb=uQf86?^(7LrDc=MZKgM4WW@_vchB(y8UKaGwP1 zLrNm(jGxko?U$MKQ?X#Yi^i%QXpA99#Bz3ngqQ|hv}OM5T(YHOZAd*x1%jRpCfYH( zjRJ=K#^sygZfWde?k(sI*}rjZ#{#)E|EL|4#N#v;>Yy%1uSe&FX%KNkV6oK>f$$2C|Do$PSGK7HNXIU37pN zs2{`&yrDaYAdXLb)K7g%B9BPb+yP{EVe!5ca zd^|w?IOgmI;&#<}7vc?*3(n>ohapsqhB%t1a3!Sv#R?i4shW1xw^}<}w0E}XXtnTr@9)2DPNUrXQuBGfILk(#JmrJP!*$C+AFb@>NFNdbo`v;Js z++l?S($gkD+!MMAB&5n0VM1xATq*4W3t2@us=?lP_H9>`&cBe z#1o~l1u0oqXaqMt2wYA+q?D7ScLhweX`68tWa+12tizkK^wu+SZS)8X6`meJph9g| z@G0!R4R;FdZy4`8s9LREl-s)~ca$<5z4=u0zr2Y5?*G3|({ZZ*e@~D9W&hXTzQZ=~ z2>v&l9cSHtc+~8s-R`t2{C^6{v7Qqx|CSH^;_o-U$v8Vs_O$1RR5HK@bVuVrB(Y z5NmQWgvU`Ku_Wxf?_u;Ou5y~iHxC6v73V9t(84Ju(O;RD`3So;3 z&U3DHelZ!G4gPrPo}9mN$MEHPZ4H|T`HHXNWv#KU)XGIz?mqWb;ZK!R6f>DaRw_tK zyZoDxRX$w_wSDD%v*d?y-`2E}7~TvW>6wM+V$ShO?k2D#Sbs7a8CSZ!+_RfY9qqw_ zAPniXj+~CEHZb`H>@3!G?nT-|Dv3a8l+bwucP1fLX5POj<>|_pp2bNVU}&g*C-c917rhg@S#m#1?z`x7 zUTtB=iIt>NgX@O9w5(t1$h>o!Qa8Zi)W>MqMfzT%oI!p|Yt9+$y|xLt6$QWONyk~u zkQY?y21Kr{d;Wt(flwV}VrCwoD2NrPEn3&LXLKfiO0K(r8;ynFbeamHJp-oP+FteF zzAO*VSeo0Kz|x+{>-QBC8#E%H&SbD{F%DGMO!Vm!GBOXo;ku`z%Olq{(evl%r;-c1 zUo;1{xeoSVi`_Ck*ENa|M$0s}bA8CXNLG`_BTo!&LCT}@;9elFR#8P2Ra8+$6;)JG YMHN+4QAHJ1RM9T<7g(w7VE`xq08dB7m;e9( literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4474b9c --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from distutils.core import setup +setup( + name = 'tinymlgen', + packages = ['tinymlgen'], + version = '0.1', + license='MIT', + description = 'Generate C code for microcontrollers from Tensorflow models', + author = 'Simone Salerno', + author_email = 'eloquentarduino@gmail.com', + url = 'https://github.com/eloquentarduino/tinymlgen', + download_url = 'https://github.com/eloquentarduino/tinymlgen/archive/v_01.tar.gz', + keywords = ['ML', 'microcontrollers', 'tensorflow', 'machine learning'], + install_requires=[ + 'tensorflow', + 'hexdump' + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Code Generators', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + ], +) \ No newline at end of file diff --git a/tinymlgen/__init__.py b/tinymlgen/__init__.py new file mode 100644 index 0000000..027ec7f --- /dev/null +++ b/tinymlgen/__init__.py @@ -0,0 +1 @@ +from tinymlgen.tinymlgen import port \ No newline at end of file diff --git a/tinymlgen/tinymlgen.py b/tinymlgen/tinymlgen.py new file mode 100644 index 0000000..61de622 --- /dev/null +++ b/tinymlgen/tinymlgen.py @@ -0,0 +1,35 @@ +import re +import hexdump +import tensorflow as tf + + +def port(model, optimize=True, variable_name='model_data', pretty_print=False): + converter = tf.lite.TFLiteConverter.from_keras_model(model) + if optimize: + if isinstance(optimize, bool): + optimizers = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE] + else: + optimizers = optimize + converter.optimizations = optimizers + tflite_model = converter.convert() + bytes = hexdump.dump(tflite_model).split(' ') + c_array = ', '.join(['0x%02x' % int(byte, 16) for byte in bytes]) + c = 'const unsigned char %s[] DATA_ALIGN_ATTRIBUTE = {%s};' % (variable_name, c_array) + if pretty_print: + c = c.replace('{', '{\n\t').replace('}', '\n}') + c = re.sub(r'(0x..?, ){12}', lambda x: '%s\n\t' % x.group(0), c) + c += '\nconst int %s_len = %d;' % (variable_name, len(bytes)) + preamble = ''' +#ifdef __has_attribute +#define HAVE_ATTRIBUTE(x) __has_attribute(x) +#else +#define HAVE_ATTRIBUTE(x) 0 +#endif +#if HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) +#define DATA_ALIGN_ATTRIBUTE __attribute__((aligned(4))) +#else +#define DATA_ALIGN_ATTRIBUTE +#endif + +''' + return preamble + c \ No newline at end of file