Code Monkey home page Code Monkey logo

simple_cnn_tutorial's Introduction

uTensor - Test Release

CircleCI Note: If you are looking for stable releases, checkout master.

Tutorials

Building Tutorial Examples

Make sure cmake is available on your system and run following commands:

$ mkdir build
$ cd build
$ cmake -DPACKAGE_TUTORIALS=ON ..
$ make

After the building process finish, you should find the tutorial executables under build/tutorials/ directory.

Follow instructions in the README.md in each tutorial directories to learn how to use uTensor.

Here are the links to the tutorials:

  1. Error Handling with uTensor
  2. Custom Operator

Introduction

What is it?

uTensor is an extremely light-weight machine learning inference framework built on Tensorflow and optimized for Arm targets. It consists of a runtime library and an offline tool that handles most of the model translation work. This repo holds the core runtime and some example implementations of operators, memory managers/schedulers, and more, and the size of the core runtime is only ~2KB!

Module .text .data .bss
uTensor/src/uTensor/core 1275(+1275) 4(+4) 28(+28)
uTensor/src/uTensor/tensors 791(+791) 0(+0) 0(+0)

How does the uTensor workflow work?

A model is constructed and trained in Tensorflow. uTensor takes the model and produces a .cpp and .hpp file. These files contains the generated C++11 code needed for inferencing. Working with uTensor on the embedded side is as easy as copy-and-paste.

How does the uTensor runtime work?

Check out the detailed description here

Release Note

The rearchitecture is fundamentally centered around a few key ideas, and the structure of the code base and build tools naturally followed. Old key points:

  • Tensors describe how data is accessed and where from
    • Performance of ops depends on which tensors are used
  • Operators are Tensor agnostic
    • High performance ops can fetch blocks of data at once
  • Strive for low total power in execution
  • Low static and dynamic footprint, be small
    • Low cost per Tensor throughout the entire system, since most generated models have 100+ including intermediates, also impacts dynamic footprint
    • Lightweight class hierarchy
    • Duh

New additional key ideas:

  • System safety
    • All tensor metadata and actual data are owned in dedicated regions
      • This can either be user provided, or one we create
    • We can guarantee that runtime will use no more than N bytes of RAM at code gen time or at compile time!
    • Generally should not collide with userspace or system space memory, i.e. dont share heaps
    • Generally implications: a safe runtime means we can safely update models remotely
    • As many compile time errors as possible!
      • Mismatched inputs, outputs, or numbers
      • wrong sizes used
      • Impossible memory accesses
      • etc.
  • Clear, Concise, and Debuggable
    • Previous iteration of uTensor relied almost too heavily on codegen, making changes to a model for any reason was near impossible
    • A developer should be able to make changes to the model without relying on code gen
    • A developer should be able to look at a model file and immediately understand what the graph looks like, without a massive amound of jumping around
    • Default tensor interface should behave like a higher level language, but exploit the speed of C++
      • Generally: No more pointer bullshit! C is super error prone, fight me
        • Only specialized operators have access to raw data blocks, and these ops will be wicked fast
    • Extensible, configurable, and optimize-outable error handling
    • GDB debugging IS NOW TRIVIAL

As mentioned before, these key ideas need to be reflected not only in the code, but in the code structure in such a way that it is Maintainable, Hackable, and User-extensible. Pretty much everything in the uTensor runtime can be divided into two components: core, and everything else. The core library contains all the deep low level functionality needed for the runtime to make the above guarantees, as well as the interfaces required for concrete implementation. Furthermore, the overhead of this core engine should be negligible relative to the system operation. Everything not in the core library really should just be thought of a reasonable defaults. For example, tensor implementations, default operators, example memory allocators, or even possible logging systems and error handlers. These modules should be the primary area for future optimization, especially before model deployment.

High level API

using namespace uTensor;

const uint8_t s_a[4] = {1, 2, 3, 4};
const uint8_t s_b[4] = {5, 6, 7, 8};
const uint8_t s_c_ref[4] = {19, 22, 43, 50};

// These can also be embedded in models
// Recommend, not putting these on the heap or stack directly as they can be large
localCircularArenaAllocator<256> meta_allocator; // All tensor metadata gets stored here automatically, even when new is called
localCircularArenaAllocator<256> ram_allocator;  // All temporary storage gets allocated here

void foo() {
  // Tell the uTensor context which allocators to use
  Context::get_default_context()->set_metadata_allocator(&meta_allocator);
  Context::get_default_context()->set_ram_data_allocator(&ram_allocator);

  // Tensors are simply handles for accessing data as necessary, they are no larger than a pointer
  // RomTensor(TensorShape, data_type, data*);
  Tensor a = new /*const*/ RomTensor({2, 2}, u8, s_a);
  Tensor b = new /*const*/ RomTensor({2, 2}, u8, s_b);
  Tensor c_ref = new RomTensor({2,2}, u8, s_c_ref);
  // RamTensors are held internally and can be moved or cleared depending on the memory schedule (optional)
  Tensor c = new RamTensor({2, 2}, u8);

  // Operators take in a fixed size map of (input_name -> parameter), this gives compile time errors on input mismatching
  // Also, the name binding + lack of parameter ordering makes ctag jumping and GDB sessions significantly more intuitive
  MatrixMultOperator<uint8_t> mult_AB;
  mult_AB
      .set_inputs({{MatrixMultOperator<uint8_t>::a, a}, {MatrixMultOperator<uint8_t>::b, b}})
      .set_outputs({{MatrixMultOperator<uint8_t>::c, c}})
      .eval();

  // Compare results
  TensorShape& c_shape = c->get_shape();
  for (int i = 0; i < c_shape[0]; i++) {
    for (int j = 0; j < c_shape[1]; j++) {
      // Just need to cast the access to the expected type
      if( static_cast<uint8_t>(c(i, j)) != static_cast<uint8_t>(c_ref(i, j)) ) {
        printf("Oh crap!\n");
        exit(-1);
      }
    }
  }
}

Building and testing locally

git clone [email protected]:uTensor/uTensor.git
cd uTensor/
git checkout proposal/rearch
git submodule init
git submodule update
mkdir build
cd build/
cmake -DPACKAGE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug ..
make
make test

Building and running on Arm Mbed OS

The uTensor core library is configured as a mbed library out of the box, so we just need to import it into our project and build as normal.

mbed new my_project
cd my_project
mbed import https://github.com/uTensor/uTensor.git
# Create main file
# Run uTensor-cli workflow and copy model directory here
mbed compile # as normal

Building and running on Arm systems

TODO Note: CMake Support for Arm is currently experimental https://stackoverflow.com/questions/46916611/cross-compiling-googletest-for-arm64

Default build

mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../extern/CMSIS_5/CMSIS/DSP/gcc.cmake  ..

With CMSIS optimized kernels

mkdir build && cd build
cmake -DARM_PROJECT=1 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../extern/CMSIS_5/CMSIS/DSP/gcc.cmake  ..

Further Reading

simple_cnn_tutorial's People

Contributors

dboyliao avatar neil-tan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

simple_cnn_tutorial's Issues

Not working: ConvOp not found !

hello, I followed the tutorial but I got errors concerning the Conv2D operation(error: "ConvOp does not name a type, do you mean.."), I searched in the repository of utensor in ops and found that it is not implemented in uTensor/ops/NnOps.hpp ! . How can I solve this problem. Please help me as soon as possible and Thank you very much !

Example not working (anymore?)

I can't get this example to work. I'm not sure if this is because of inconsistencies with newer dependencies but everything I tried was unsuccessful. This is what I tried so far:

The first error I get when following the example step by step is

Traceback (most recent call last):
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/bin/utensor-cli", line 5, in <module>
    from utensor_cgen.cli import cli
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/utensor_cgen/cli.py", line 8, in <module>
    from .utils import NArgsParam
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/utensor_cgen/utils.py", line 11, in <module>
    from tensorflow.tools.graph_transforms import TransformGraph
ImportError: No module named graph_transforms

which is because tensorflow 2.1.0 was installed by pip install utensor_cgen==0.3.3.dev2

So I downgraded tensorflow to 1.13.2 but then I just run into the next error:

utensor-cli convert cifar10_cnn.pb --output-nodes=fully_connect_2/logits

WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.
For more information, please see:
  * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md
  * https://github.com/tensorflow/addons
If you depend on functionality not listed there, please file an issue.

Traceback (most recent call last):
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/bin/utensor-cli", line 8, in <module>
    sys.exit(cli())
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/utensor_cgen/cli.py", line 84, in convert_graph
    generator.generate(model_path)
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/utensor_cgen/backend/code_generator.py", line 49, in generate
    parser_cls = FrontendSelector.select_parser(ext)
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/utensor_cgen/frontend/__init__.py", line 26, in select_parser
    cls._setup()
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/utensor_cgen/frontend/__init__.py", line 46, in _setup
    importlib.import_module(mod_name)
  File "/Users/cglaser/.pyenv/versions/2.7.15/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/utensor_cgen/frontend/onnx.py", line 2, in <module>
    from onnx_tf.backend import prepare
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/onnx_tf/__init__.py", line 1, in <module>
    from . import backend
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/onnx_tf/backend.py", line 29, in <module>
    from onnx_tf.common.handler_helper import get_all_backend_handlers
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/onnx_tf/common/handler_helper.py", line 5, in <module>
    from onnx_tf.handlers.backend import *  # noqa
  File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/onnx_tf/handlers/backend/scatter_nd.py", line 8, in <module>
    @tf_func(tf.tensor_scatter_nd_update)
AttributeError: 'module' object has no attribute 'tensor_scatter_nd_update'
make: *** [models/cifar10_cnn.cpp] Error 1

I get the same error also for python 3.7.3.

I then tried upgrading utensor_cgen to the latest release, but this also crashes maybe because it is not python2.7 compatible anymore?

pip install utensor_cgen --upgrade
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Collecting utensor_cgen
  Using cached https://files.pythonhosted.org/packages/a2/a3/d6db368011e481e38dce7b209d3818942b5dc157ef8b528b8cf3bf414d64/utensor_cgen-0.4.2.tar.gz
    ERROR: Command errored out with exit status 1:
     command: /Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/bin/python2.7 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/setup.py'"'"'; __file__='"'"'/private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/pip-egg-info
         cwd: /private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/
    Complete output (24 lines):
    DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/setup.py", line 79, in <module>
        "Topic :: Utilities"
      File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/setuptools/__init__.py", line 145, in setup
        return distutils.core.setup(**attrs)
      File "/Users/cglaser/.pyenv/versions/2.7.15/lib/python2.7/distutils/core.py", line 111, in setup
        _setup_distribution = dist = klass(attrs)
      File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/setuptools/dist.py", line 448, in __init__
        k: v for k, v in attrs.items()
      File "/Users/cglaser/.pyenv/versions/2.7.15/lib/python2.7/distutils/dist.py", line 287, in __init__
        self.finalize_options()
      File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/setuptools/dist.py", line 740, in finalize_options
        ep.load()(self)
      File "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial/.venv/lib/python2.7/site-packages/setuptools/dist.py", line 747, in _finalize_setup_keywords
        ep.load()(self, ep.name, value)
      File "/private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/.eggs/better_setuptools_git_version-1.0.5-py2.7.egg/better_setuptools_git_version.py", line 82, in validate_version_config
        dist.metadata.version = get_version(template, starting_version)
      File "/private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/.eggs/better_setuptools_git_version-1.0.5-py2.7.egg/better_setuptools_git_version.py", line 52, in get_version
        tag = get_tag()
      File "/private/var/folders/bt/vcs5g33x3mn05hx6tn023ssc0000gn/T/pip-install-OxAhcH/utensor-cgen/.eggs/better_setuptools_git_version-1.0.5-py2.7.egg/better_setuptools_git_version.py", line 9, in get_tag
        return subprocess.getoutput("git tag --sort=version:refname --merged | tail -n1")
    AttributeError: 'module' object has no attribute 'getoutput'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

With python3 I upgraded utensor_cgen to the latest version which also downgraded tensorflow to 1.13.1
Successfully installed graphviz-0.13.2 onnx-tf-1.2.1 tensorflow-1.13.1 toml-0.10.0 utensor-cgen-0.4.2

This allows to execute utensor-cli convert cifar10_cnn.pb --output-nodes fully_connect_2/logits without errors.

However, the compilation of the mbed code then crashes with

mbed compile -m auto -t GCC_ARM --profile=uTensor/build_profile/release.json -f
[mbed] Working path "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial_p3" (program)
[mbed] WARNING: Could not find mbed program in current path "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial_p3".
       You can fix this by calling "mbed new ." in the root of your program.
---
[mbed] Detected "K64F" connected to "/Volumes/DAPLINK" and using com port "/dev/tty.usbmodem1422"
[Warning] @,: Compiler version mismatch: Have 9.2.1; expected version >= 6.0.0 and < 7.0.0
Building project simple_cnn_tutorial_p3 (K64F, GCC_ARM)
Scan: simple_cnn_tutorial_p3
...
Compile [ 85.2%]: mbed_rtc_time.cpp
[Error] mbed_rtc_time.cpp@89,22: invalid use of incomplete type 'const struct timeval'
[Error] mbed_rtc_time.cpp@110,7: invalid use of incomplete type 'struct timeval'
[Error] mbed_rtc_time.cpp@111,7: invalid use of incomplete type 'struct timeval'
[Error] mbed_rtc_time.cpp@124,20: aggregate 'timeval tv' has incomplete type and cannot be defined
[Error] mbed_rtc_time.cpp@137,26: variable 'const timeval tv' has initializer but incomplete type
[ERROR] '_queue.SimpleQueue' object has no attribute 'queue'
[mbed] ERROR: "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial_p3/.venv/bin/python" returned error.
       Code: 1
       Path: "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial_p3"
       Command: "/Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial_p3/.venv/bin/python -u /Users/cglaser/work/ARIANNA/analysis/2019deeplearning/classification/uTensor_examples/simple_cnn_tutorial_p3/mbed-os/tools/make.py -t GCC_ARM -m K64F --profile uTensor/build_profile/release.json --source . --build ./BUILD/K64F/GCC_ARM-RELEASE"
       Tip: You could retry the last command with "-v" flag for verbose output
---
make: *** [compile] Error 255

Maybe this is because my compiler version is too high? [Warning] @,: Compiler version mismatch: Have 9.2.1; expected version >= 6.0.0 and < 7.0.0
So I downgraded my GCC_ARM toolchain to 6.3.1 but I still get the same error.

Any help would be greatly appreciated!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.