From 588f79a62bf70f8070dc2814adb2f6f87eee147d Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 17 Jul 2020 19:56:46 +0200 Subject: [PATCH] Remove legacy CMSIS-NN code and examples. --- ml/cmsisnn/README.md | 121 ---- ml/cmsisnn/models/cifar10/cifar10.network | Bin 89970 -> 0 bytes .../models/cifar10/cifar10_solver.prototxt | 30 - .../cifar10/cifar10_train_test.prototxt | 196 ------ ml/cmsisnn/models/cifar10/test.sh | 8 - ml/cmsisnn/models/cifar10/train.sh | 8 - .../models/cifar10_fast/cifar10_fast.network | Bin 33602 -> 0 bytes .../cifar10_fast/cifar10_fast_solver.prototxt | 30 - .../cifar10_fast_train_test.prototxt | 196 ------ ml/cmsisnn/models/cifar10_fast/test.sh | 8 - ml/cmsisnn/models/cifar10_fast/train.sh | 8 - ml/cmsisnn/models/lenet/lenet.network | Bin 106984 -> 0 bytes ml/cmsisnn/models/lenet/lenet_solver.prototxt | 25 - .../models/lenet/lenet_train_test.prototxt | 170 ----- ml/cmsisnn/models/lenet/test.sh | 8 - ml/cmsisnn/models/lenet/train.sh | 8 - ml/cmsisnn/models/smile/smile.network | Bin 23882 -> 0 bytes ml/cmsisnn/models/smile/smile_solver.prototxt | 30 - .../models/smile/smile_train_test.prototxt | 230 ------- ml/cmsisnn/models/smile/test.sh | 8 - ml/cmsisnn/models/smile/train.sh | 8 - ml/cmsisnn/nn_convert.py | 197 ------ ml/cmsisnn/nn_quantizer.py | 638 ------------------ ml/cmsisnn/nn_run_all.sh | 16 - .../25-Machine-Learning/nn_cifar10.py | 33 - .../nn_cifar10_search_just_center.py | 53 -- .../nn_cifar10_search_whole_window.py | 47 -- .../nn_haar_smile_detection.py | 37 - .../examples/25-Machine-Learning/nn_lenet.py | 31 - .../nn_lenet_search_just_center.py | 51 -- .../nn_lenet_search_whole_window.py | 45 -- 31 files changed, 2240 deletions(-) delete mode 100644 ml/cmsisnn/README.md delete mode 100644 ml/cmsisnn/models/cifar10/cifar10.network delete mode 100644 ml/cmsisnn/models/cifar10/cifar10_solver.prototxt delete mode 100644 ml/cmsisnn/models/cifar10/cifar10_train_test.prototxt delete mode 100755 ml/cmsisnn/models/cifar10/test.sh delete mode 100755 ml/cmsisnn/models/cifar10/train.sh delete mode 100644 ml/cmsisnn/models/cifar10_fast/cifar10_fast.network delete mode 100644 ml/cmsisnn/models/cifar10_fast/cifar10_fast_solver.prototxt delete mode 100644 ml/cmsisnn/models/cifar10_fast/cifar10_fast_train_test.prototxt delete mode 100755 ml/cmsisnn/models/cifar10_fast/test.sh delete mode 100755 ml/cmsisnn/models/cifar10_fast/train.sh delete mode 100644 ml/cmsisnn/models/lenet/lenet.network delete mode 100644 ml/cmsisnn/models/lenet/lenet_solver.prototxt delete mode 100644 ml/cmsisnn/models/lenet/lenet_train_test.prototxt delete mode 100755 ml/cmsisnn/models/lenet/test.sh delete mode 100755 ml/cmsisnn/models/lenet/train.sh delete mode 100644 ml/cmsisnn/models/smile/smile.network delete mode 100644 ml/cmsisnn/models/smile/smile_solver.prototxt delete mode 100644 ml/cmsisnn/models/smile/smile_train_test.prototxt delete mode 100755 ml/cmsisnn/models/smile/test.sh delete mode 100755 ml/cmsisnn/models/smile/train.sh delete mode 100644 ml/cmsisnn/nn_convert.py delete mode 100644 ml/cmsisnn/nn_quantizer.py delete mode 100755 ml/cmsisnn/nn_run_all.sh delete mode 100644 scripts/examples/25-Machine-Learning/nn_cifar10.py delete mode 100644 scripts/examples/25-Machine-Learning/nn_cifar10_search_just_center.py delete mode 100644 scripts/examples/25-Machine-Learning/nn_cifar10_search_whole_window.py delete mode 100644 scripts/examples/25-Machine-Learning/nn_haar_smile_detection.py delete mode 100644 scripts/examples/25-Machine-Learning/nn_lenet.py delete mode 100644 scripts/examples/25-Machine-Learning/nn_lenet_search_just_center.py delete mode 100644 scripts/examples/25-Machine-Learning/nn_lenet_search_whole_window.py diff --git a/ml/cmsisnn/README.md b/ml/cmsisnn/README.md deleted file mode 100644 index 74ff2b37a..000000000 --- a/ml/cmsisnn/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# CMSIS-NN - -This folder contains scripts to train, test, and quantize Caffe models and then convert them to an 8-bit binary format for running on the OpenMV Cam. - -## Getting started -1. Setup your computer for deep-learning: - 1. CPU Only - https://www.pyimagesearch.com/2017/09/25/configuring-ubuntu-for-deep-learning-with-python/ - 2. GPU (recommended) - https://www.pyimagesearch.com/2017/09/27/setting-up-ubuntu-16-04-cuda-gpu-for-deep-learning-with-python/ -2. Install caffe: - 1. `pushd ~` (in the folder this READMD.md is in) - 2. `git clone --recursive https://github.com/BVLC/caffe.git` - 3. Follow https://github.com/BVLC/caffe/wiki/Ubuntu-16.04-or-15.10-Installation-Guide - 4. Add `export PYTHONPATH=/home//caffe/:$PYTHONPATH` to your `~/.bashrc` file. - 5. `source ~/.bashrc` - 6. `popd` - 7. `ln -s ~/caffe caffe` (in the folder this READMD.md is in) -3. Read http://adilmoujahid.com/posts/2016/06/introduction-deep-learning-python-caffe/ - -## Training a CIFAR10 Model -1. Now we're going to train a CIFAR10 Model. - 1. Open a terminal in this folder. - 2. First we need to get the data and create an lmdb. - 1. `cd caffe` - 2. `./data/cifar10/get_cifar10.sh` - 3. `./examples/cifar10/create_cifar10.sh` - 4. `./build/tools/compute_image_mean -backend=lmdb examples/cifar10/cifar10_train_lmdb examples/cifar10/mean.binaryproto` - 3. Next we need to train our network. - 1. `cd ..` - 2. `./models/cifar10/train.sh` - This takes a while. -2. Great! Now let's test and then convert the network. - 1. `./models/cifar10/test.sh` - You should get an accuracy of about 80%. - 2. `python2 nn_quantizer.py --gpu --model models/cifar10/cifar10_train_test.prototxt --weights models/cifar10/cifar10_iter_70000.caffemodel.h5 --save models/cifar10/cifar10.pkl` - Note how the accuracy stays at about 80%. - 3. `python2 nn_convert.py --model models/cifar10/cifar10.pkl --mean caffe/examples/cifar10/mean.binaryproto --output models/cifar10/cifar10.network`. - 4. And that's it! You've created a CNN that will run on the OpenMV Cam! Keep in mind that your OpenMV Cam has limited weight/bias heap space so this limits the size of the network. To run the CNN copy the `models/cifar10/cifar10.network` file to your OpenMV Cam's disk and then run our CIFAR10 Machine Learning Examples. - -## Training a CIFAR10 Fast Model -1. Now we're going to train a CIFAR10 Fast Model which is 60% smaller than the cifar10 network with only a 2% loss in accurary. - 1. Open a terminal in this folder. - 2. First we need to get the data and create an lmdb. - 1. `cd caffe` - 2. `./data/cifar10/get_cifar10.sh` - 3. `./examples/cifar10/create_cifar10.sh` - 4. `./build/tools/compute_image_mean -backend=lmdb examples/cifar10/cifar10_train_lmdb examples/cifar10/mean.binaryproto` - 3. Next we need to train our network. - 1. `cd ..` - 2. `./models/cifar10_fast/train.sh` - This takes a while. -2. Great! Now let's test and then convert the network. - 1. `./models/cifar10_fast/test.sh` - You should get an accuracy of about 78%. - 2. `python2 nn_quantizer.py --gpu --model models/cifar10_fast/cifar10_fast_train_test.prototxt --weights models/cifar10_fast/cifar10_fast_iter_70000.caffemodel.h5 --save models/cifar10_fast/cifar10_fast.pkl` - Note how the accuracy stays at about 78%. - 3. `python2 nn_convert.py --model models/cifar10_fast/cifar10_fast.pkl --mean caffe/examples/cifar10/mean.binaryproto --output models/cifar10_fast/cifar10_fast.network`. - 4. And that's it! You've created a CNN that will run on the OpenMV Cam! Keep in mind that your OpenMV Cam has limited weight/bias heap space so this limits the size of the network. To run the CNN copy the `models/cifar10_fast/cifar10_fast.network` file to your OpenMV Cam's disk and then run our CIFAR10 Machine Learning Examples using the cifar10_fast.network. - -## Training a MNIST Model -1. Now we're going to train a MNIST Model. - 1. Open a terminal in this folder. - 2. First we need to get the data and create an lmdb. - 1. `cd caffe` - 2. `./data/mnist/get_mnist.sh` - 3. `./examples/mnist/create_mnist.sh` - 4. `./build/tools/compute_image_mean -backend=lmdb examples/mnist/mnist_train_lmdb examples/mnist/mean.binaryproto` - 3. Next we need to train our network. - 1. `cd ..` - 2. `./models/lenet/train.sh` - This takes a while. -2. Great! Now let's test and then convert the network. - 1. `./models/lenet/test.sh` - You should get an accuracy of about 99%. - 2. `python2 nn_quantizer.py --gpu --model models/lenet/lenet_train_test.prototxt --weights models/lenet/lenet_iter_10000.caffemodel --save models/lenet/lenet.pkl` - Note how the accuracy stays at about 99%. - 3. `python2 nn_convert.py --model models/lenet/lenet.pkl --mean caffe/examples/mnist/mean.binaryproto --output models/lenet/lenet.network`. - 4. And that's it! You've created a CNN that will run on the OpenMV Cam! Keep in mind that your OpenMV Cam has limited weight/bias heap space so this limits the size of the network. To run the CNN copy the `models/lenet/lenet.network` file to your OpenMV Cam's disk and then run our LENET Machine Learning Examples. - -## Training a Smile Detection Model -1. Now we're going to train a Smile Detection Model. - 1. Open a terminal in this folder. - 2. First we need to get the data and create an lmdb. - 1. `cd caffe/examples` - 2. `mkdir smile` - 3. `cd smile` - 4. `git clone --recursive https://github.com/hromi/SMILEsmileD.git` - 5. `cd ../../../../..` - 6. The SMILEsmileD dataset has about ~3K positive images and ~9K negative images so we need to augment our positive image dataset so that it is about the same size as our negative image dataset. - 1. `mkdir ml/cmsisnn/caffe/examples/smile/data` - 2. `cp -r ml/cmsisnn/caffe/examples/smile/SMILEsmileD/SMILEs/negatives/negatives7/ ml/cmsisnn/caffe/examples/smile/data/1_negatives` - 3. `sudo pip2 install opencv-python imgaug tqdm` - 4. `mkdir ml/cmsisnn/caffe/examples/smile/data/0_positives` - 5. `python2 tools/augment_images.py --input ml/cmsisnn/caffe/examples/smile/SMILEsmileD/SMILEs/positives/positives7/ --output ml/cmsisnn/caffe/examples/smile/data/0_positives/ --count 3` - 7. Now we need to create an lmdb. - 1. `mkdir ml/cmsisnn/caffe/examples/smile/lmdbin` - 2. `python2 tools/create_labels.py --input ml/cmsisnn/caffe/examples/smile/data/ --output ml/cmsisnn/caffe/examples/smile/lmdbin/` - 3. `cd ml/cmsisnn/caffe/` - 4. `GLOG_logtostderr=1 ./build/tools/convert_imageset --shuffle examples/smile/lmdbin/ examples/smile/train.txt examples/smile/train_lmdb` - 5. `GLOG_logtostderr=1 ./build/tools/convert_imageset --shuffle examples/smile/lmdbin/ examples/smile/test.txt examples/smile/test_lmdb` - 8. `./build/tools/compute_image_mean -backend=lmdb examples/smile/train_lmdb examples/smile/mean.binaryproto` - 3. Next we need to train our network. - 1. `cd ..` - 2. `./models/smile/train.sh` - This takes a while. -2. Great! Now let's test and then convert the network. - 1. `./models/smile/test.sh` - You should get an accuracy of about 96%. - 2. `python2 nn_quantizer.py --gpu --model models/smile/smile_train_test.prototxt --weights models/smile/smile_iter_200000.caffemodel --save models/smile/smile.pkl` - Note how the accuracy stays at about 96%. - 3. `python2 nn_convert.py --model models/smile/smile.pkl --mean caffe/examples/smile/mean.binaryproto --output models/smile/smile.network`. - 4. And that's it! You've created a CNN that will run on the OpenMV Cam! Keep in mind that your OpenMV Cam has limited weight/bias heap space so this limits the size of the network. To run the CNN copy the `models/smile/smile.network` file to your OpenMV Cam's disk and then run our Smile Machine Learning Example. - -### Train A Custom Net -If you'd like to train your own custom CNN you need to assemble a dataset of hundreds (preferably thousands) of images of training examples. Once you've collected all the training examples save the images per class of training examples in seperate folders structed like this: -* data/ - * 0_some_class/ - * 1_some_other_class/ - * 2_etc/ - -Once you've built a folder structure like this please refer to the examples above to: -1. Create a labeled training dataset using augment_images.py and create_labels.py. -2. Create training and test lmdb files. -3. Create a mean.binaryproto file. -4. Train the network (copy how the smile train.sh script and solver/train/test protobufs work to do this). -5. Test the network (copy how the smile test.sh script and solver/train/test protobufs works to do this). -6. Quantize the network. -7. And finally convert the network. - -### Known Limitations -1. Parser supports conv, pool, relu, fc layers only. -2. Quantizer supports only networks with feed-forward structures (e.g. conv-relu-pool-fc) without branch-out/branch-in (as in inception/squeezeNet, etc.). -3. See [ARM ML-examples](https://github.com/ARM-software/ML-examples/tree/master/cmsisnn-cifar10) for more information. -4. Source Code https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/NN diff --git a/ml/cmsisnn/models/cifar10/cifar10.network b/ml/cmsisnn/models/cifar10/cifar10.network deleted file mode 100644 index 25984226b410527bac8210f59deb8d1f7163873a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89970 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%0AR6!O9k7nUIXpqitfl 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 diff --git a/ml/cmsisnn/models/cifar10/cifar10_solver.prototxt b/ml/cmsisnn/models/cifar10/cifar10_solver.prototxt deleted file mode 100644 index f0dd05e4b..000000000 --- a/ml/cmsisnn/models/cifar10/cifar10_solver.prototxt +++ /dev/null @@ -1,30 +0,0 @@ -# reduce learning rate after 120 epochs (60000 iters) by factor 0f 10 -# then another factor of 10 after 10 more epochs (5000 iters) - -# The train/test net protocol buffer definition -net: "models/cifar10/cifar10_train_test.prototxt" -# test_iter specifies how many forward passes the test should carry out. -# In the case of CIFAR10, we have test batch size 100 and 100 test iterations, -# covering the full 10,000 testing images. -test_iter: 100 -# Carry out testing every 1000 training iterations. -test_interval: 1000 -# The base learning rate, momentum and the weight decay of the network. -base_lr: 0.001 -momentum: 0.9 -weight_decay: 0.004 -# The learning rate policy -lr_policy: "multistep" -gamma: 0.1 -stepvalue: 60000 -stepvalue: 65000 -# Display every 200 iterations -display: 200 -# The maximum number of iterations -max_iter: 70000 -# snapshot intermediate results -snapshot: 10000 -snapshot_format: HDF5 -snapshot_prefix: "models/cifar10/cifar10" -# solver mode: CPU or GPU -solver_mode: GPU diff --git a/ml/cmsisnn/models/cifar10/cifar10_train_test.prototxt b/ml/cmsisnn/models/cifar10/cifar10_train_test.prototxt deleted file mode 100644 index 32c223635..000000000 --- a/ml/cmsisnn/models/cifar10/cifar10_train_test.prototxt +++ /dev/null @@ -1,196 +0,0 @@ -name: "CIFAR10_full" -layer { - name: "data" - type: "Data" - top: "data" - top: "label" - include { - phase: TRAIN - } - transform_param { - mean_file: "caffe/examples/cifar10/mean.binaryproto" - } - data_param { - source: "caffe/examples/cifar10/cifar10_train_lmdb" - batch_size: 100 - backend: LMDB - } -} -layer { - name: "data" - type: "Data" - top: "data" - top: "label" - include { - phase: TEST - } - transform_param { - mean_file: "caffe/examples/cifar10/mean.binaryproto" - } - data_param { - source: "caffe/examples/cifar10/cifar10_test_lmdb" - batch_size: 100 - backend: LMDB - } -} -layer { - name: "conv1" - type: "Convolution" - bottom: "data" - top: "conv1" - param { - lr_mult: 1 - } - param { - lr_mult: 2 - } - convolution_param { - num_output: 32 - pad: 2 - kernel_size: 5 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.0001 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "pool1" - type: "Pooling" - bottom: "conv1" - top: "pool1" - pooling_param { - pool: MAX - kernel_size: 3 - stride: 2 - } -} -layer { - name: "relu1" - type: "ReLU" - bottom: "pool1" - top: "pool1" -} -layer { - name: "conv2" - type: "Convolution" - bottom: "pool1" - top: "conv2" - param { - lr_mult: 1 - } - param { - lr_mult: 2 - } - convolution_param { - num_output: 32 - pad: 2 - kernel_size: 5 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "relu2" - type: "ReLU" - bottom: "conv2" - top: "conv2" -} -layer { - name: "pool2" - type: "Pooling" - bottom: "conv2" - top: "pool2" - pooling_param { - pool: AVE - kernel_size: 3 - stride: 2 - } -} -layer { - name: "conv3" - type: "Convolution" - bottom: "pool2" - top: "conv3" - convolution_param { - num_output: 64 - pad: 2 - kernel_size: 5 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "relu3" - type: "ReLU" - bottom: "conv3" - top: "conv3" -} -layer { - name: "pool3" - type: "Pooling" - bottom: "conv3" - top: "pool3" - pooling_param { - pool: AVE - kernel_size: 3 - stride: 2 - } -} -layer { - name: "ip1" - type: "InnerProduct" - bottom: "pool3" - top: "ip1" - param { - lr_mult: 1 - decay_mult: 250 - } - param { - lr_mult: 2 - decay_mult: 0 - } - inner_product_param { - num_output: 10 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "accuracy" - type: "Accuracy" - bottom: "ip1" - bottom: "label" - top: "accuracy" - include { - phase: TEST - } -} -layer { - name: "loss" - type: "SoftmaxWithLoss" - bottom: "ip1" - bottom: "label" - top: "loss" -} diff --git a/ml/cmsisnn/models/cifar10/test.sh b/ml/cmsisnn/models/cifar10/test.sh deleted file mode 100755 index 432ba1520..000000000 --- a/ml/cmsisnn/models/cifar10/test.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -e - -TOOLS=./caffe/build/tools - -$TOOLS/caffe test \ - --model=models/cifar10/cifar10_train_test.prototxt \ - --weights=models/cifar10/cifar10_iter_70000.caffemodel.h5 $@ diff --git a/ml/cmsisnn/models/cifar10/train.sh b/ml/cmsisnn/models/cifar10/train.sh deleted file mode 100755 index 80c2b8600..000000000 --- a/ml/cmsisnn/models/cifar10/train.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -e - -DIR=models/cifar10 -TOOLS=./caffe/build/tools - -$TOOLS/caffe train \ - --solver=models/cifar10/cifar10_solver.prototxt $@ 2>&1 | tee $DIR/training.log diff --git a/ml/cmsisnn/models/cifar10_fast/cifar10_fast.network b/ml/cmsisnn/models/cifar10_fast/cifar10_fast.network deleted file mode 100644 index 44e3fc30a718661f0def12a53be64caf1a03822e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33602 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 diff --git a/ml/cmsisnn/models/cifar10_fast/cifar10_fast_solver.prototxt b/ml/cmsisnn/models/cifar10_fast/cifar10_fast_solver.prototxt deleted file mode 100644 index 2b9a41edb..000000000 --- a/ml/cmsisnn/models/cifar10_fast/cifar10_fast_solver.prototxt +++ /dev/null @@ -1,30 +0,0 @@ -# reduce learning rate after 120 epochs (60000 iters) by factor 0f 10 -# then another factor of 10 after 10 more epochs (5000 iters) - -# The train/test net protocol buffer definition -net: "models/cifar10_fast/cifar10_fast_train_test.prototxt" -# test_iter specifies how many forward passes the test should carry out. -# In the case of CIFAR10, we have test batch size 100 and 100 test iterations, -# covering the full 10,000 testing images. -test_iter: 100 -# Carry out testing every 1000 training iterations. -test_interval: 1000 -# The base learning rate, momentum and the weight decay of the network. -base_lr: 0.001 -momentum: 0.9 -weight_decay: 0.004 -# The learning rate policy -lr_policy: "multistep" -gamma: 0.1 -stepvalue: 60000 -stepvalue: 65000 -# Display every 200 iterations -display: 200 -# The maximum number of iterations -max_iter: 70000 -# snapshot intermediate results -snapshot: 10000 -snapshot_format: HDF5 -snapshot_prefix: "models/cifar10_fast/cifar10_fast" -# solver mode: CPU or GPU -solver_mode: GPU diff --git a/ml/cmsisnn/models/cifar10_fast/cifar10_fast_train_test.prototxt b/ml/cmsisnn/models/cifar10_fast/cifar10_fast_train_test.prototxt deleted file mode 100644 index 8d87a8d8f..000000000 --- a/ml/cmsisnn/models/cifar10_fast/cifar10_fast_train_test.prototxt +++ /dev/null @@ -1,196 +0,0 @@ -name: "CIFAR10_fast" -layer { - name: "data" - type: "Data" - top: "data" - top: "label" - include { - phase: TRAIN - } - transform_param { - mean_file: "caffe/examples/cifar10/mean.binaryproto" - } - data_param { - source: "caffe/examples/cifar10/cifar10_train_lmdb" - batch_size: 100 - backend: LMDB - } -} -layer { - name: "data" - type: "Data" - top: "data" - top: "label" - include { - phase: TEST - } - transform_param { - mean_file: "caffe/examples/cifar10/mean.binaryproto" - } - data_param { - source: "caffe/examples/cifar10/cifar10_test_lmdb" - batch_size: 100 - backend: LMDB - } -} -layer { - name: "conv1" - type: "Convolution" - bottom: "data" - top: "conv1" - param { - lr_mult: 1 - } - param { - lr_mult: 2 - } - convolution_param { - num_output: 32 - pad: 2 - kernel_size: 5 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.0001 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "pool1" - type: "Pooling" - bottom: "conv1" - top: "pool1" - pooling_param { - pool: MAX - kernel_size: 3 - stride: 2 - } -} -layer { - name: "relu1" - type: "ReLU" - bottom: "pool1" - top: "pool1" -} -layer { - name: "conv2" - type: "Convolution" - bottom: "pool1" - top: "conv2" - param { - lr_mult: 1 - } - param { - lr_mult: 2 - } - convolution_param { - num_output: 16 - pad: 2 - kernel_size: 5 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "relu2" - type: "ReLU" - bottom: "conv2" - top: "conv2" -} -layer { - name: "pool2" - type: "Pooling" - bottom: "conv2" - top: "pool2" - pooling_param { - pool: AVE - kernel_size: 3 - stride: 2 - } -} -layer { - name: "conv3" - type: "Convolution" - bottom: "pool2" - top: "conv3" - convolution_param { - num_output: 32 - pad: 2 - kernel_size: 5 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "relu3" - type: "ReLU" - bottom: "conv3" - top: "conv3" -} -layer { - name: "pool3" - type: "Pooling" - bottom: "conv3" - top: "pool3" - pooling_param { - pool: AVE - kernel_size: 3 - stride: 2 - } -} -layer { - name: "ip1" - type: "InnerProduct" - bottom: "pool3" - top: "ip1" - param { - lr_mult: 1 - decay_mult: 250 - } - param { - lr_mult: 2 - decay_mult: 0 - } - inner_product_param { - num_output: 10 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "accuracy" - type: "Accuracy" - bottom: "ip1" - bottom: "label" - top: "accuracy" - include { - phase: TEST - } -} -layer { - name: "loss" - type: "SoftmaxWithLoss" - bottom: "ip1" - bottom: "label" - top: "loss" -} diff --git a/ml/cmsisnn/models/cifar10_fast/test.sh b/ml/cmsisnn/models/cifar10_fast/test.sh deleted file mode 100755 index 953f06062..000000000 --- a/ml/cmsisnn/models/cifar10_fast/test.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -e - -TOOLS=./caffe/build/tools - -$TOOLS/caffe test \ - --model=models/cifar10_fast/cifar10_fast_train_test.prototxt \ - --weights=models/cifar10_fast/cifar10_fast_iter_70000.caffemodel.h5 $@ diff --git a/ml/cmsisnn/models/cifar10_fast/train.sh b/ml/cmsisnn/models/cifar10_fast/train.sh deleted file mode 100755 index f1e6a690a..000000000 --- a/ml/cmsisnn/models/cifar10_fast/train.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -e - -DIR=models/cifar10_fast -TOOLS=./caffe/build/tools - -$TOOLS/caffe train \ - --solver=models/cifar10_fast/cifar10_fast_solver.prototxt $@ 2>&1 | tee $DIR/training.log diff --git a/ml/cmsisnn/models/lenet/lenet.network b/ml/cmsisnn/models/lenet/lenet.network deleted file mode 100644 index 660156e1afa13ceb50180969ec878e5db3e2774b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106984 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 | tee $DIR/training.log diff --git a/ml/cmsisnn/models/smile/smile.network b/ml/cmsisnn/models/smile/smile.network deleted file mode 100644 index 72a045839e099cc51e1373739ef9a2ff1672abe9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23882 zcmZ_0*{&_gb{!TGnUQ_7y4{_=sxEKekhCR=l0i_kuVDdt@v~sSfWN|jA^(8=Bm>q1 zAM6JMhG>zd=u3j)C3(B*>(n`CH>=H+eMUy>v8#AtTDG&WcCEcnu9aQHoMVnLX8foB z^gsV`O1|EH6aVw@`u)Fq{kQo4uU|3VQ@kGcd4<>S|J@7!BMDxQpL_iG$Jc+2U(z&f z+Gd{TwrxNDO;6dPjwFP0ozuH3l^{WjZ#zrYMUv1VHrKD0yYkhff zS=Tk*-{0T=(I5TMPk!>}-~ZnC7-M;!<2&~IJ-+gAIQ;adKi%ziFJHdIug{-9e|UH} z9*_9WrfK@V55o}O;2c>lm-y6I2P4=MCx-V@%4wX05Ysf_gK-?==Z7DDD8#(kY&_3< z_3Bj=MK~zVFbG0?1Run&IK9VH{Ax2A=d8Xye|#a{W5aQ=;Zt8-Hx6g9FZRKKqA12U zlI~DQ|ABaaK6c z*XM?xcp~@}CyArrCq9VVh?DvH5LuRCm%lr8ZE$Gph7Bi!`}6hB`uukr?hH-<8xDtK z;fT0J_&3~qJU#rpy}iA;xxqcbp4bP6!1?3*zuy1rH~1s|6&v1Q!mi4q_~Ta>?R|Y3_=!P)GslMA zaPl}Sd;|8u;qXXt&j0sme|7S>5PS+dV+Y(feE(M?B*0(r{_#$J^&idwf5*cy_VFCB z;Zt8f5sXs&t9AD40gpp>U5AT3?DshO>({R_=709HpW%w|Ygv}Ba3qXbeEsA9zWU|w z-kQggz~3-3@#a6AuaB4T>%YCi`^VSg_PFok_W1wD!SnyMPlUh!{drElffHz5N}^dL zoOGh6?&4|)xktQUo=yXyL8*0^1?9yuX~Gj92O1J#o?Sej&5+2_Wrwpk*nV_PaIUlE z+;5_KDyVlI4zx*F@R>ZP&d$MExPxQ1@!t?l!*PndIOw@??bB`l@Z< z;^6nGEW@huI!71ICZRI5Nshs>Pb1!qYR<;!iB{3sBwwmw8Hi!-Mq+g>5Dv`0zwb%S zh_K@}2+plHdmqHrS@{EZWE8Z1dpdaBBvdp_<$X9O)5I*L$E4_pK9kzN6BHL4vo~Xv z%UyR&+I(tNup_1=M;6 z^rMhug533Ss#3=0V6n1>3;u3A6H9m-jb0y~Y1~$DbQ z(2=DY9K#MKjr-nX!ll`vkEb}qH8Zk}%TTVy3(eitFbT>%w}~2m(eWt|$7OIxrwbyx zAQCgf)GtPRqWQtx1l4fvi9dJL^J5X8&XM!i)wtN)xKyi|m^={C#d9sf?>?y;CbFiB z`txiS<-DMSUk$Mq0X>dWAGuyn+)?XOubX0xc$e8rJjpa-u_rT^2eH9-uG`Bu>YGp2 zG>-y8`DK?@< zMV@~R=XI7IQ?W{`;Gy2#`LnBq37qD! zAJI_!nggsZf?=BvHN4WYa&*refqnovp&@{5%`S>s~n(85i60(oUkhZsszcEYWE!1F$aa`L6M0@pdd#>^v>Vv4~_gY_vTo@6G7WY*50f69-6Ob;k{D+fpI#OGdlZ=#hXk&ko$ra}POu zp1icznWBvJ(|8Qo(x`;nz=a_RkpzOHoLvze)T~}B?_hT+y>e6t-QUZ>qs~>WKjh)m zE)89>hu6FhlbFQu(2m^W%zyhuDzE7|PL{3mXi(Ghac0@sGL4X8WxCRp#aF%^e|w z#bXxr$vR0Q-{eW7Mq_#I9S!nHC;R@PB_fI_k?Cxu$^#WN)u4$Ca~9S4><2w?Q4*-> zXqeZS-p={i_;#;7^CVEJ4kI$Kjbe%-IE5R^b!0U2V>yY)zqfpm#iE(H3Vph>oaDVA zOJnOIb~J5OdFiWpRg9z!r0Ydy#3IOQ=4g17$`7svbKyl7VW7_QID|y{1(CgPsXur# zoo&$cp|6LStY;EwHJuQvA`fumF5^w>Wve*}y_)I#)@H|1RcdHrgw9R{W8C}ckfrfVryyWs+B)evUbr)zF%=7M>O59(FRodAOazmncXHb6 zgrBQfo@a@H6VRpdW`8~vTQBi@wH!obE$hQs*MXmTX*%~OJhz6$E>#|(E=v{^_g}7* zUfo$crVBdq%Zw~UvvXR}qdvO(nAp@e?fPyKv&T=dx9yopBbA$StPzQ=6Va%n1>q7m zTLo-NRpbMhC6I|74`Afj?mSbc6l!K2iF!H>M8fMG!bvy#;myS&MI86 zi&uFZ964#SZ%dvc>khh-DF(2Q7!}&Z;ejM$u*!?6DYoTv8fa4E@pCiTW{|y&#;R+V zY~HZIx##yM)6YvF2HRYomNIu-+|Mj3ZR+YFF>Bi=ANS(ui4QxPFVBE1gU$L}V`J#=rFZAgm)o52Bk|PncMS=5{>x zJ}aqz;-wb7zEV%x`=HHz#F%NA4^AES)lkv!E={OMkc+4!^#U3Oo3W6E+pQ|peSLAEK47kOtvGwyq=OlUDC$A@${T7l9u z6e5@=Z@o!8e|7F7po@6kzD)rSG_08zF;=t8lXD1hzb?l8n)^C*xR^k*3b-JjGPqg)P6E^3@ zHF7XM!iQ>u^FC8-%iXvPn1#sn7wlXK@pg{+QRcGSNwZ+fFid^htpNW3aWSBs z$S33H-pP;V@NGl|C!3~8?WJr*+eS}l;)e1TWgivA^1e^i*v$19a~5QDams|sy^T#< zpbNKTe#V}l4Ev3zl^3>Vto?6|cJV4k`dRg~@u!T|#Ebm=a#A6isUH`)pRgj1LsV`| z=DLy0xIE1q23tU;6-J!8oqOSYQx1GlwCCPY|9)EUSnUU_nZu-Zgljq_Rbp+}kHk;= zou?*`2a=8e`CHTmA)_~sBth%QN%H(8`lr5()N0O3FAD1;EoJPrVG$BOTQZ%SOIHTP zGLGu`%FD+wtH|C>#1+aGF0NzOyS5M84v60deN>SIfH+}^9yhmMX2#hYwoM)lVds-z zuwyBykB}3mZkoB3&AVt5xmmklfx(knYFF5ShFXaZU+6ZDH`7l0btDE?)u;5-ubq?x zQ`F>fwQ0|$Jsytd`q*yC!p?>rzRl*{6nB7qp{Q^R^)Di+{bM#A0R*KXAiQMS+32aMXc5m|AUFJIxF^|Y`8+rg#x8W*Y|>5O*-%~ikpci8*Wob@;>BCClOUDD~(c-@Mj-tRrHa$_tdF28?RY0*z1V8(~`9r?&qSGi^K*mGphacAT~Ty{`+Yd;=Ki`se|wIpENF zcgbp^rj%_p3-iMEX`A9>L$zQLap6Feu&Fw)AKSsxu@%=>oGV} zBT+F=B>(=-eDBrTZP=p02OtrQ%8QpZ!KG zktL4&dwol@A+sS_&}LbTEmA&PIfPQm3>ZB&23O`-%e#`tHk|>5Q`O4qi#KPIG~RL~ z>w0CnA$q3h`&KrMDu@I3q>jRe-qOBV5(JY#i$mwx{?jum!MvaMeNEWu zh?0ehwimLf;!z7(f8INz*dkHCtU^&a{%UAf$UnPCr(R#vbpJUg(=r9&>rJ6Jjk*h` zNDh58mW?@8MQ!3U;<5{C7n?PR(bbqvMTi^> zgkD9Yct!Nk1>Ad**=Zd~YE+ua_}Y2vk#}S$pF1^XJs)nE$`G8`1MBX&$;U^MlQ8-2 zp0s4a5RRrORQKAcpd07>glgYB)NcN4WKp{}v{Avq=#wxg;_)Q+8P{D^j;@m|zqs&b z(OOdnf;x*KMEwr5@P$FC19}P^#AJ1!3d<4?NhUPO2=+yxKn@Q%AVL#GHdWS@NxuTD zq;VyMBB4m!X)WEol!%GRpoPaLn-69iB%SSg#!A04N`Q<|SC$+9yfc1clFT1%)()Od zB^#_NV_=Y_59kXNH?yVgA4aKKJH#AUK2~$s7+oMMXVwQ9XhI*ca$0~)5BW&u5Y@a- z)$S~O%pIQxaXKFtJ&I>XqJs73xN5Il&;x3jhPLr&FPp@_L3ZG!pZC%h2X+%W$&q1n zIHpuhS_2+Xt2_Ceb3_~Kv1Nt23OBDyw}L6zdx+qpeOdJ@w^#J3&pdo{ax&ywW$h$_OEt3t$K zfO1<-j{7^n6*eMdzaLzMj>OW9y6?GtqTC6PGaAO4=e`3dEqc1qG%G{z&qc2 zM)o!!B-pTMP@Ug%5enSQVP{V7l-;Bpgivq*r#QvE?H6E_%z3N;90mZj=nHMhjPU4j z+vmk{8R>CnwqE7is{KS#Zeqidp%E*i<5DGQ#ba=6&g5*-A1N+@;(J$ppPq+&r1se6 zTo9nd$s4=R-^Arvj?4H%6)lW#UXR+ujHfD)1@U6{sa$|hdYs};cf|(-&DZSiatHpi zJZ{niG0Igc2uN^qYIP5=4c>N^&JTq{9jV5>Kprb2{gl(8^u>JXfzHj^Xq{8%H1b}Y><1nRO_Ha4WwB*V$7tN5xytQou@ANpW8)bc>I?O;1Wa32I zL!dXc*fd?Ix>=Q^G{-qpApLtS71c-`3c$gk*0R2h6sb+9bGxOkr3J~AP0I;|PsG5- zhNGf3E62xB$bAD?FqwcH!QZ{b;9)@$)!lj2aUdCS)tFY~>Kq5%c~bqFC@R$GPt=8A z-YG@N6?+5tDyEM>jUy)`YOPsiKBF;akGdg7PqE~;xm&rT32H@><dX1+{vgLoJr~}7M!8=ng(i`V^P1!-4NNZYYL4NamwZp=LCoNkwC3OxViT^- zx<9o?M`PD53d1$%WTNjDi|uH`=#G;MG8GeZnho;m)cI_rBdvJ(ELWb4IuN2N%<9mO zx3gH3y=m0EJqL~Li`6``H86M_T%J{w^$Doz@Z88L?9Acro*Bk7z_NQUt8F~Yc5~Cv zZdifslH(Qk4;S}ikiI00&W+|B4V3HRDsV#!pYNd+ z^3(HCQ%`4LWv?0zHd!Mo9{MwP2ibr(qd5l{)$4bOhXO@I+37|bX<>-awhkpRl&|^$ zG+;6XXEm)r9wcTlj)f2QDxpq#i_8{*>a9(AWjiZD!Jqs2Ju{?^Nn^qZ9E||eA5BxM zHz9K@<*fEx;15jOVPc6&2*-fD`C_Tr1AXHaZ_ zpN4_5J~7?G)n?(1)4ag$|;mUtoUrW)+N^&|gn7-38qu2kY4xcfRNT z{YdGE@H6w}DJu3KYjBrIZ_SsR%D=eS`vuc7U9Ow82i|sd^Zjp2sApD*A6_f>ji+u= zuAiU!=((yjUvff!aEYV}L|S~~Y8>4128@8P{L+1qmINABqo z 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 diff --git a/ml/cmsisnn/models/smile/smile_solver.prototxt b/ml/cmsisnn/models/smile/smile_solver.prototxt deleted file mode 100644 index 8e49a607f..000000000 --- a/ml/cmsisnn/models/smile/smile_solver.prototxt +++ /dev/null @@ -1,30 +0,0 @@ -# The train/test net protocol buffer definition -net: "models/smile/smile_train_test.prototxt" -# Specifies how many forward passes the test should carry out. -# Test batch size 48*30 iterations = 1440 testing images. -test_iter: 30 -# Carry out testing every 1000 training iterations. -test_interval: 1000 -# The learning rate policy -# begin training at a learning rate of 0.01 = 1e-2 -base_lr: 0.01 -momentum: 0.9 -weight_decay: 0.00001 -# learning rate policy: drop the learning rate in -# "steps" by a factor of gamma every stepsize iterations -lr_policy: "step" -# drop the learning rate by a factor of 10 -# (i.e., multiply it by a factor of gamma = 0.1) -gamma: 0.1 -# Drop the learning rate every 10K iterations -stepsize: 10000 -# train for 100K iterations total -max_iter: 60000 -# Display every 100 iterations -display: 100 -# snapshot intermediate results -snapshot: 20000 -snapshot_format: HDF5 -snapshot_prefix: "models/smile/smile" -# solver mode: CPU or GPU -solver_mode: GPU diff --git a/ml/cmsisnn/models/smile/smile_train_test.prototxt b/ml/cmsisnn/models/smile/smile_train_test.prototxt deleted file mode 100644 index ddb4a43f6..000000000 --- a/ml/cmsisnn/models/smile/smile_train_test.prototxt +++ /dev/null @@ -1,230 +0,0 @@ -name: "SmileNet" -layer { - name: "data" - type: "Data" - top: "data" - top: "label" - include { - phase: TRAIN - } - transform_param { - mean_file: "caffe/examples/smile/mean.binaryproto" - } - data_param { - source: "caffe/examples/smile/train_lmdb" - batch_size: 100 - backend: LMDB - } -} -layer { - name: "data" - type: "Data" - top: "data" - top: "label" - include { - phase: TEST - } - transform_param { - mean_file: "caffe/examples/smile/mean.binaryproto" - } - data_param { - source: "caffe/examples/smile/test_lmdb" - batch_size: 48 - backend: LMDB - } -} -layer { - name: "conv1" - type: "Convolution" - bottom: "data" - top: "conv1" - param { - lr_mult: 1 - } - param { - lr_mult: 2 - } - convolution_param { - num_output: 32 - pad: 1 - kernel_size: 3 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.0001 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "dropout1" - type: "Dropout" - bottom: "conv1" - top: "conv1" - dropout_param { - dropout_ratio: 0.5 - } - include { - phase: TRAIN - } -} -layer { - name: "relu1" - type: "ReLU" - bottom: "conv1" - top: "conv1" -} -layer { - name: "pool1" - type: "Pooling" - bottom: "conv1" - top: "pool1" - pooling_param { - pool: MAX - kernel_size: 2 - stride: 2 - } -} -layer { - name: "conv2" - type: "Convolution" - bottom: "pool1" - top: "conv2" - param { - lr_mult: 1 - } - param { - lr_mult: 2 - } - convolution_param { - num_output: 32 - pad: 1 - kernel_size: 3 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "dropout2" - type: "Dropout" - bottom: "conv2" - top: "conv2" - dropout_param { - dropout_ratio: 0.25 - } - include { - phase: TRAIN - } -} -layer { - name: "relu2" - type: "ReLU" - bottom: "conv2" - top: "conv2" -} -layer { - name: "pool2" - type: "Pooling" - bottom: "conv2" - top: "pool2" - pooling_param { - pool: AVE - kernel_size: 2 - stride: 2 - } -} -layer { - name: "conv3" - type: "Convolution" - bottom: "pool2" - top: "conv3" - convolution_param { - num_output: 32 - pad: 1 - kernel_size: 3 - stride: 1 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "dropout3" - type: "Dropout" - bottom: "conv3" - top: "conv3" - dropout_param { - dropout_ratio: 0.3 - } - include { - phase: TRAIN - } -} -layer { - name: "relu3" - type: "ReLU" - bottom: "conv3" - top: "conv3" -} -layer { - name: "pool3" - type: "Pooling" - bottom: "conv3" - top: "pool3" - pooling_param { - pool: AVE - kernel_size: 2 - stride: 2 - } -} -layer { - name: "ip1" - type: "InnerProduct" - bottom: "pool3" - top: "ip1" - param { - lr_mult: 1 - } - param { - lr_mult: 2 - } - inner_product_param { - num_output: 2 - weight_filler { - type: "gaussian" - std: 0.01 - } - bias_filler { - type: "constant" - } - } -} -layer { - name: "accuracy" - type: "Accuracy" - bottom: "ip1" - bottom: "label" - top: "accuracy" - include { - phase: TEST - } -} -layer { - name: "loss" - type: "SoftmaxWithLoss" - bottom: "ip1" - bottom: "label" - top: "loss" -} diff --git a/ml/cmsisnn/models/smile/test.sh b/ml/cmsisnn/models/smile/test.sh deleted file mode 100755 index e00561b8e..000000000 --- a/ml/cmsisnn/models/smile/test.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -e - -TOOLS=./caffe/build/tools - -$TOOLS/caffe test \ - --model=models/smile/smile_train_test.prototxt \ - --weights=models/smile/smile_iter_60000.caffemodel.h5 $@ diff --git a/ml/cmsisnn/models/smile/train.sh b/ml/cmsisnn/models/smile/train.sh deleted file mode 100755 index 5f86e41d1..000000000 --- a/ml/cmsisnn/models/smile/train.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env sh -set -e - -DIR=models/smile -TOOLS=./caffe/build/tools - -$TOOLS/caffe train \ - --solver=models/smile/smile_solver.prototxt $@ 2>&1 | tee $DIR/training.log diff --git a/ml/cmsisnn/nn_convert.py b/ml/cmsisnn/nn_convert.py deleted file mode 100644 index 15dfa2a7a..000000000 --- a/ml/cmsisnn/nn_convert.py +++ /dev/null @@ -1,197 +0,0 @@ -# This file is part of the OpenMV project. -# -# Copyright (c) 2013-2019 Ibrahim Abdelkader -# Copyright (c) 2013-2019 Kwabena W. Agyeman -# -# This work is licensed under the MIT license, see the file LICENSE for details. -# -# CMSIS NN binary converter. - -import numpy as np -import pickle, struct -import os, sys, caffe, argparse -from nn_quantizer import * -from caffe.proto import caffe_pb2 -from google.protobuf import text_format - -caffe_layers = { - 'data' : 0, - 'convolution' : 1, - 'relu' : 2, - 'pooling' : 3, - 'innerproduct' : 4 -} - -def get_mean_values(mean_file): - mean_vals = [0, 0, 0] - if (mean_file): - with open(mean_file, 'rb') as f: - data = f.read() - blob = caffe.proto.caffe_pb2.BlobProto() - blob.ParseFromString(data) - arr = np.array(caffe.io.blobproto_to_array(blob))[0] - mean_vals = [int(x.mean().round()) for x in arr] - if (len(mean_vals) < 3): - mean_vals += [mean_vals[0]] * (3 - len(mean_vals)) - return mean_vals - -def convert_to_x4_weights(weights): - """This function convert the fully-connected layer weights - to the format that accepted by X4 implementation""" - [r, h, w, c] = weights.shape - weights = np.reshape(weights, (r, h*w*c)) - num_of_rows = r - num_of_cols = h*w*c - new_weights = np.copy(weights) - new_weights = np.reshape(new_weights, (r*h*w*c)) - counter = 0 - for i in range(int(num_of_rows)/4): - # we only need to do the re-ordering for every 4 rows - row_base = 4*i - for j in range (int(num_of_cols)/4): - # for each 4 entries - column_base = 4*j - new_weights[counter] = weights[row_base ][column_base ] - new_weights[counter+1] = weights[row_base+1][column_base ] - new_weights[counter+2] = weights[row_base ][column_base+2] - new_weights[counter+3] = weights[row_base+1][column_base+2] - new_weights[counter+4] = weights[row_base+2][column_base ] - new_weights[counter+5] = weights[row_base+3][column_base ] - new_weights[counter+6] = weights[row_base+2][column_base+2] - new_weights[counter+7] = weights[row_base+3][column_base+2] - - new_weights[counter+8] = weights[row_base ][column_base+1] - new_weights[counter+9] = weights[row_base+1][column_base+1] - new_weights[counter+10] = weights[row_base ][column_base+3] - new_weights[counter+11] = weights[row_base+1][column_base+3] - new_weights[counter+12] = weights[row_base+2][column_base+1] - new_weights[counter+13] = weights[row_base+3][column_base+1] - new_weights[counter+14] = weights[row_base+2][column_base+3] - new_weights[counter+15] = weights[row_base+3][column_base+3] - counter = counter + 16 - # the remaining ones are in order - for j in range((int)(num_of_cols-num_of_cols%4), int(num_of_cols)): - new_weights[counter] = weights[row_base][j] - new_weights[counter+1] = weights[row_base+1][j] - new_weights[counter+2] = weights[row_base+2][j] - new_weights[counter+3] = weights[row_base+3][j] - counter = counter + 4 - return new_weights - -def dump_network(caffe_model, file_name): - fout = open(file_name, 'wb') - net = caffe.Net(caffe_model.model_file, caffe_model.quant_weight_file, caffe.TEST) - - # Write network type - fout.write(struct.pack('4c', 'C', 'A', 'F', 'E')) - - num_layers = 0 - # Check and count layers - for layer in caffe_model.layer: - layer_type = caffe_model.layer_type[layer] - if layer_type in caffe_layers: - num_layers += 1 - elif layer_type != 'accuracy': - print("Layer %s is not supported, can't convert this network."%(layer_type)) - sys.exit(1) - - # Write number of layers - fout.write(struct.pack('i', num_layers)) - - for layer in caffe_model.layer: - layer_no = caffe_model.layer.index(layer) - layer_type = caffe_model.layer_type[layer] - - if not layer_type in caffe_layers: - print('NOTE: skipping layer "%s"' %(layer_type)) - continue - - if layer_no > 0: - prev_layer = caffe_model.layer[layer_no-1] - - # Write layer type code - fout.write(struct.pack('i', caffe_layers[layer_type])) - - # Write layer shape (n, c, h, w) - shape = [x for x in caffe_model.layer_shape[layer]] - if (len(shape) < 4): shape += [1] * (4 - len(shape)) - fout.write(struct.pack('4i', *shape)) - caffe_model.layer_shape[layer] = shape - - print('Layer: {0: <8} Type: {1: <15}Shape: {2: <20}'.format(layer, layer_type, str(shape))) - - if layer_type == 'data': - # Write r_mean, g_mean, b_mean - mean_values = get_mean_values(model.mean_file) - fout.write(struct.pack('3i', *mean_values)) - # Write input scale - fout.write(struct.pack('i', 8-caffe_model.act_dec_bits[layer])) - - if layer_type == 'pooling': - # Write pool type - fout.write(struct.pack('i', caffe_model.pool_type[layer])) - - if layer_type in ['convolution', 'innerproduct']: - # Write lshift, rshift - fout.write(struct.pack('i', max(0, caffe_model.bias_lshift[layer]))) - fout.write(struct.pack('i', max(0, caffe_model.act_rshift[layer]))) - - if layer_type in ['convolution', 'pooling']: - # Write k_size, k_pad, k_stride - fout.write(struct.pack('i', caffe_model.kernel_size[layer])) - fout.write(struct.pack('i', caffe_model.pad[layer])) - fout.write(struct.pack('i', caffe_model.stride[layer])) - - if layer_type == 'convolution': - net.params[layer][0].data[:] = np.round(net.params[layer][0].data*(2**caffe_model.wt_dec_bits[layer])) - net.params[layer][1].data[:] = np.round(net.params[layer][1].data*(2**caffe_model.bias_dec_bits[layer])) - - #CHW to HWC layout conversion - reordered_wts = np.swapaxes(np.swapaxes(net.params[layer][0].data, 1, 2), 2, 3).flatten() - - # Write weights size and array - fout.write(struct.pack('i', len(reordered_wts))) - for i in reordered_wts: fout.write(struct.pack('b', i)) - - # Write bias size and array - fout.write(struct.pack('i', len(net.params[layer][1].data))) - for i in net.params[layer][1].data: fout.write(struct.pack('b', i)) - - if layer_type == 'innerproduct': - net.params[layer][0].data[:]=np.round(net.params[layer][0].data*(2**caffe_model.wt_dec_bits[layer])) - net.params[layer][1].data[:]=np.round(net.params[layer][1].data*(2**caffe_model.bias_dec_bits[layer])) - layer_no = caffe_model.layer.index(layer) - prev_layer_name = caffe_model.layer[layer_no-1] #needed to find input shape of 'ip' layer - if(len(caffe_model.layer_shape[prev_layer_name])>2): #assuming HWC input format - reshaped_shape = (caffe_model.layer_shape[layer][1],caffe_model.layer_shape[prev_layer_name][1],\ - caffe_model.layer_shape[prev_layer_name][2],caffe_model.layer_shape[prev_layer_name][3]) - reordered_wts = np.reshape(net.params[layer][0].data, reshaped_shape) - # Reorder the weights to use fully_connected_x4 kernel - reordered_wts = np.swapaxes(np.swapaxes(reordered_wts, 1, 2), 2, 3) - reordered_wts = convert_to_x4_weights(reordered_wts) - else: - reordered_wts = net.params[layer][0].data.flatten() - - # Write weights size and array - fout.write(struct.pack('i', len(reordered_wts))) - for i in reordered_wts: fout.write(struct.pack('b', i)) - - # Write bias size and array - fout.write(struct.pack('i', len(net.params[layer][1].data))) - for i in net.params[layer][1].data: fout.write(struct.pack('b', i)) - - fout.close() - - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--model', type=str, help='model info') - parser.add_argument('--mean', type=str, help='mean image file') - parser.add_argument('--output',type=str, default="cifar10.network", help='output file') - - args, _ = parser.parse_known_args() - - model = Caffe_Quantizer() - model.load_quant_params(args.model) - model.mean_file = args.mean if (args.mean) else None - dump_network(model, args.output) diff --git a/ml/cmsisnn/nn_quantizer.py b/ml/cmsisnn/nn_quantizer.py deleted file mode 100644 index 45d60dc0a..000000000 --- a/ml/cmsisnn/nn_quantizer.py +++ /dev/null @@ -1,638 +0,0 @@ -# Copyright (C) 2018 Arm Limited or its affiliates. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the License); you may -# not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an AS IS BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# NN-Quantizer for Caffe models - -import sys -# Include /python in PYTHONPATH environment variable -import os -import caffe -from caffe.proto import caffe_pb2 -import numpy as np -import argparse -from google.protobuf import text_format -import pickle - -class Caffe_Quantizer(object): - """\ - Quantize a trained caffe model to 8-bits - """ - def __init__(self,model_file='',weight_file='',iterations=100, - accuracy_layer='accuracy',gpu=False): - self.model_file=model_file - self.weight_file=weight_file - self.quant_weight_file="" - self.conv_layer=[] - self.ip_layer=[] - self.start_layer=[] - self.end_layer=[] - self.layer=[] - self.layer_shape={} - self.layer_wt_shape={} - self.top_blob={} - self.bottom_blob={} - self.layer_type={} - self.kernel_size={} - self.stride={} - self.pad={} - self.group={} - self.pool_type={} - self.lrn_type={} - self.lrn_size={} - self.lrn_alpha={} - self.lrn_beta={} - self.num_ops={} - self.num_wts={} - self.wt_int_bits={} - self.wt_dec_bits={} - self.bias_int_bits={} - self.bias_dec_bits={} - self.act_int_bits={} - self.act_dec_bits={} - self.bias_lshift={} - self.act_rshift={} - self.data_layer=None - self.label_layer=None - self.accuracy_layer=accuracy_layer - self.iterations=iterations - self.gpu=gpu - - def save_quant_params(self,model_info_file): - pickle.dump(self,open(model_info_file,'wb')) - - def load_quant_params(self,model_info_file): - model_par=pickle.load(open(model_info_file,'rb')) - self.model_file=model_par.model_file - self.weight_file=model_par.weight_file - self.quant_weight_file=model_par.quant_weight_file - self.conv_layer=model_par.conv_layer - self.ip_layer=model_par.ip_layer - self.start_layer=model_par.start_layer - self.end_layer=model_par.end_layer - self.layer=model_par.layer - self.layer_shape=model_par.layer_shape - self.layer_wt_shape=model_par.layer_wt_shape - self.top_blob=model_par.top_blob - self.bottom_blob=model_par.bottom_blob - self.layer_type=model_par.layer_type - self.kernel_size=model_par.kernel_size - self.stride=model_par.stride - self.pad=model_par.pad - self.group=model_par.group - self.pool_type=model_par.pool_type - self.lrn_type=model_par.lrn_type - self.lrn_size=model_par.lrn_size - self.lrn_alpha=model_par.lrn_alpha - self.lrn_beta=model_par.lrn_beta - self.num_ops=model_par.num_ops - self.num_wts=model_par.num_wts - self.wt_int_bits=model_par.wt_int_bits - self.wt_dec_bits=model_par.wt_dec_bits - self.bias_int_bits=model_par.bias_int_bits - self.bias_dec_bits=model_par.bias_dec_bits - self.act_int_bits=model_par.act_int_bits - self.act_dec_bits=model_par.act_dec_bits - self.bias_lshift=model_par.bias_lshift - self.act_rshift=model_par.act_rshift - self.data_layer=model_par.data_layer - self.label_layer=model_par.label_layer - self.accuracy_layer=model_par.accuracy_layer - self.iterations=model_par.iterations - self.gpu=model_par.gpu - - def run_full_network(self): - if self.gpu==True: - caffe.set_mode_gpu() - net = caffe.Net(self.model_file,self.weight_file,caffe.TEST) - acc = np.zeros(self.iterations) - for i in range(0,self.iterations): - out = net.forward() - acc[i] = out[self.accuracy_layer]*100 - print("Full precision accuracy: %.2f%%" %(acc.mean())) - return acc.mean() - - def run_quantized_network(self): - if self.gpu==True: - caffe.set_mode_gpu() - net = caffe.Net(self.model_file,self.quant_weight_file,caffe.TEST) - acc = np.zeros(self.iterations) - for i in range(0,self.iterations): - out = net.forward() - acc[i] = out[self.accuracy_layer]*100 - print("Accuracy with quantized weights/biases: %.2f%%" %(acc.mean())) - for i in range(0,self.iterations): - for layer_no in range(0,len(self.start_layer)): - if layer_no==0: - net.forward(end=str(self.end_layer[layer_no])) - else: - net.forward(start=str(self.start_layer[layer_no]),end=str(self.end_layer[layer_no])) - if layer_no < len(self.start_layer)-1: # not quantizing accuracy layer - net.blobs[self.end_layer[layer_no]].data[:]=np.floor(net.blobs[self.end_layer[layer_no]].data*\ - (2**self.act_dec_bits[self.end_layer[layer_no]])) - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data>126]=127 - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data<-127]=-128 - net.blobs[self.end_layer[layer_no]].data[:]=net.blobs[self.end_layer[layer_no]].data/\ - (2**self.act_dec_bits[self.end_layer[layer_no]]) - acc[i] = net.blobs[self.accuracy_layer].data*100 - accuracy = acc.mean() - print("Accuracy with quantized weights/biases and activations: %.2f%%" %(accuracy)) - return accuracy - - def get_layer_info(self): - net=caffe_pb2.NetParameter() - text_format.Merge(open(self.model_file,'r').read(),net) - cnn = caffe.Net(self.model_file,self.weight_file,caffe.TEST) - - if len(net.layer)==0: #some prototxts use "layer", some use "layers" - layers = net.layers - else: - layers = net.layer - - for layer in layers: - layer_name=[] - for val in layer.top: - layer_name+=[str(val)] - self.top_blob[str(layer.name)]=layer_name - self.layer_shape[str(layer.name)]=cnn.blobs[self.top_blob[str(layer.name)][0]].data.shape - layer_name=[] - for val in layer.bottom: - layer_name+=[str(val)] - self.bottom_blob[str(layer.name)]=layer_name - self.layer_type[str(layer.name)] = str(layer.type).lower() - - if str(layer.type).lower() == 'convolution' or str(layer.type)=='4': - self.layer_wt_shape[str(layer.name)]=cnn.params[self.top_blob[str(layer.name)][0]][0].data.shape - self.conv_layer.append(str(layer.name)) - self.kernel_size[str(layer.name)] = layer.convolution_param.kernel_size[0] - self.stride[str(layer.name)] = 1; - self.pad[str(layer.name)] = 0; - if(len(layer.convolution_param.stride)!=0): - self.stride[str(layer.name)] = layer.convolution_param.stride[0] - if(len(layer.convolution_param.pad)!=0): - self.pad[str(layer.name)] = layer.convolution_param.pad[0] - self.group[str(layer.name)] = layer.convolution_param.group - elif str(layer.type).lower() == 'pooling' or str(layer.type)=='17': - self.pool_type[str(layer.name)] = layer.pooling_param.pool - self.kernel_size[str(layer.name)] = layer.pooling_param.kernel_size - self.stride[str(layer.name)] = layer.pooling_param.stride - self.pad[str(layer.name)] = layer.pooling_param.pad - elif str(layer.type).lower() == 'lrn' or str(layer.type)=='15': - self.lrn_type[str(layer.name)] = layer.lrn_param.norm_region - self.lrn_size[str(layer.name)] = layer.lrn_param.local_size - self.lrn_alpha[str(layer.name)] = layer.lrn_param.alpha - self.lrn_beta[str(layer.name)] = layer.lrn_param.beta - elif str(layer.type).lower() == 'innerproduct' or str(layer.type)=='14': - self.layer_wt_shape[str(layer.name)]=cnn.params[self.top_blob[str(layer.name)][0]][0].data.shape - self.ip_layer.append(str(layer.name)) - elif str(layer.type).lower() == 'data' or str(layer.type)=='5': - included = False - for layer_phase in layer.include: - included = included or layer_phase.phase == caffe.TEST - if(included == True): - batch_size = layer.data_param.batch_size - self.data_layer = str(layer.top[0]) - self.label_layer = str(layer.top[1]) - - def get_graph_connectivity(self): - - # Extract network connectivity for running CNN functions in the correct order - # Traversing back from output layer (accuracy) to input layer (data) especially because - # googLeNet has many accuracy labels, which branch out and end at a different accuracy - # label with forward traversal - - net=caffe_pb2.NetParameter() - text_format.Merge(open(self.model_file,'r').read(),net) - allowed_layer_types = ['data','convolution','innerproduct','pooling','lrn','relu',\ - 'accuracy','concat','5','4','14','17','15','18','1','3'] - current_layer = self.accuracy_layer - traversed=[] - while current_layer != str(self.data_layer): - traversed += [current_layer] - num_branch = len(self.bottom_blob[current_layer]) - current_blob = self.bottom_blob[current_layer][0] - has_unused_relu = 0 - for key, value in self.top_blob.iteritems(): - if (current_blob in value) and (key not in traversed) and \ - (self.layer_type[key] == 'relu' or self.layer_type[key]=='18'): - has_unused_relu = 1 - break - for key, value in self.top_blob.iteritems(): - if(has_unused_relu == 1): - if (current_blob in value) and (key not in traversed) and \ - (self.layer_type[key]=='relu' or self.layer_type[key]=='18'): - has_unused_relu = 0 - current_layer = key - break - else: - if (current_blob in value) and (key not in traversed) and \ - (self.layer_type[key] in allowed_layer_types): - current_layer = key - break - traversed += [current_layer] - traversed.reverse() - self.layer=traversed[:] - - self.start_layer+=[''] - for layer_no in range(0,len(self.layer)): - layer = self.layer[layer_no] - if layer == self.data_layer or layer in self.conv_layer or \ - layer in self.ip_layer or layer in self.accuracy_layer or\ - ((self.layer_type[layer]=='pooling' or self.layer_type[layer]=='17') \ - and self.pool_type[layer]==1): - self.end_layer+=[layer] - if layer_no < len(self.layer)-1: - self.start_layer+=[self.layer[layer_no+1]] - print(self.start_layer) - print(self.end_layer) - - # Quantize weights to 8 bits - # Using min and max of weights as nearest power of 2, quantize to 8bits (QM.N) and check accuracy - # If accuracy is lost, try QM-1:N+1, QM-2,N+2,... with saturation to find out the best combination - # with least accuracy loss (Trading-off weights that occur infrequently for more precision) - # - # -2^(M+N) 0 2^(M+N) - # | ^ | - # | *|||* | - # <--------| *|||||* |-------> - # Saturated| *|||||||* |Saturated - # | *|||||||||||* | - # | *|||||||||||||||||* | - # *| |* - # * |<-------------------------->| * - # Weight quantization and - # truncation with minimal - # loss of accuracy - # - - def quantize_wts_8bit(self,tolerance=0.001,search_range=3): - if self.gpu==True: - caffe.set_mode_gpu() - net = caffe.Net(self.model_file,self.weight_file,caffe.TEST) - acc = np.zeros(self.iterations) - for i in range(0,self.iterations): - out = net.forward() - acc[i] = out[self.accuracy_layer]*100 - target_accuracy = acc.mean() - print("Full precision accuracy: %.2f%%" %(target_accuracy)) - self.quant_weight_file = self.weight_file - wfile = os.path.basename(self.weight_file) - qwfile = 'quantized_'+wfile - self.quant_weight_file = self.weight_file.replace(wfile,qwfile) - self.quant_weight_file = self.quant_weight_file.replace('.h5','') - net.save(self.quant_weight_file) - for layer_name in self.conv_layer+self.ip_layer: - #Start with min/max of weights to the rounded up to nearest power of 2. - wt_max = net.params[layer_name][0].data.max() - wt_min = net.params[layer_name][0].data.min() - self.wt_int_bits[layer_name] = int(np.ceil(np.log2(max(abs(wt_min),abs(wt_max))))) - self.wt_dec_bits[layer_name] = 7-self.wt_int_bits[layer_name] - max_int_bits = self.wt_int_bits[layer_name]-search_range - print('Layer: '+ layer_name + ' weights max: '+str(wt_max)+' min: '+str(wt_min)+\ - ' Format: Q'+str(self.wt_int_bits[layer_name])+'.'+str(self.wt_dec_bits[layer_name])) - net.params[layer_name][0].data[:]=np.round(net.params[layer_name][0].data*\ - (2**self.wt_dec_bits[layer_name]))/(2**self.wt_dec_bits[layer_name]) - for i in range(0,self.iterations): - out = net.forward() - acc[i] = out[self.accuracy_layer]*100 - accuracy = acc.mean() - print("Accuracy: %.2f%%" %(accuracy)) - best_int_bits = self.wt_int_bits[layer_name] - best_dec_bits = self.wt_dec_bits[layer_name] - best_accuracy = accuracy - while target_accuracy-accuracy>tolerance and self.wt_int_bits[layer_name]>max_int_bits: - self.wt_int_bits[layer_name] = self.wt_int_bits[layer_name]-1 - self.wt_dec_bits[layer_name] = self.wt_dec_bits[layer_name]+1 - net.copy_from(self.quant_weight_file) - net.params[layer_name][0].data[:]=np.round(net.params[layer_name][0].data*\ - (2**self.wt_dec_bits[layer_name])) - net.params[layer_name][0].data[net.params[layer_name][0].data>126]=127 - net.params[layer_name][0].data[net.params[layer_name][0].data<-127]=-128 - net.params[layer_name][0].data[:]=net.params[layer_name][0].data/\ - (2**self.wt_dec_bits[layer_name]) - for i in range(0,self.iterations): - out = net.forward() - acc[i] = out[self.accuracy_layer]*100 - accuracy = acc.mean() - print('Format Q'+str(self.wt_int_bits[layer_name])+'.'+\ - str(self.wt_dec_bits[layer_name])+' Accuracy: %.2f%%' %(accuracy)) - if accuracy>best_accuracy: - best_int_bits = self.wt_int_bits[layer_name] - best_dec_bits = self.wt_dec_bits[layer_name] - best_accuracy = accuracy - self.wt_int_bits[layer_name] = best_int_bits - self.wt_dec_bits[layer_name] = best_dec_bits - net.copy_from(self.quant_weight_file) - net.params[layer_name][0].data[:]=np.round(net.params[layer_name][0].data*\ - (2**self.wt_dec_bits[layer_name])) - net.params[layer_name][0].data[net.params[layer_name][0].data>126]=127 - net.params[layer_name][0].data[net.params[layer_name][0].data<-127]=-128 - net.params[layer_name][0].data[:]=net.params[layer_name][0].data/\ - (2**self.wt_dec_bits[layer_name]) - print('Final '+layer_name+ ' weights format Q'+str(best_int_bits)+'.'+\ - str(best_dec_bits)+' Accuracy: %.2f%%' %(best_accuracy)) - net.save(self.quant_weight_file) - - # Quantize activations (inter-layer data) to 8 bits - # Using min and max of activations as nearest power of 2, quantize to 8bits (QM.N) and check accuracy - # If accuracy is lost, try QM-1:N+1, QM-2,N+2,... with saturation to find out the best combination - # with least accuracy loss (Trading-off activations that occur infrequently for more precision) - - def quantize_activations_8bit(self,tolerance=0.001,search_range=3): - if self.gpu==True: - caffe.set_mode_gpu() - net = caffe.Net(self.model_file,self.quant_weight_file,caffe.TEST) - acc = np.zeros(self.iterations) - for i in range(0,self.iterations): - out = net.forward() - acc[i] = out[self.accuracy_layer]*100 - target_accuracy = acc.mean() - print("Accuracy with quantized weights: %.2f%%" %(target_accuracy)) - max_val={} - min_val={} - quant_layer_flag={} - for layer in self.end_layer: - max_val[layer]=float('-inf') - min_val[layer]=float('inf') - quant_layer_flag[layer]=0 - #Finding min max for output of all layers - for i in range(0,self.iterations): - for layer_no in range(0,len(self.start_layer)): - if layer_no==0: - net.forward(end=str(self.end_layer[layer_no])) - else: - net.forward(start=str(self.start_layer[layer_no]),end=str(self.end_layer[layer_no])) - layer_max = net.blobs[self.end_layer[layer_no]].data.max() - layer_min = net.blobs[self.end_layer[layer_no]].data.min() - if(layer_max>max_val[self.end_layer[layer_no]]): - max_val[self.end_layer[layer_no]]=layer_max - if(layer_minquant_max_val[self.end_layer[layer_no]]): - quant_max_val[self.end_layer[layer_no]]=layer_max - if(layer_mintolerance and self.act_int_bits[quant_layer]>\ - max_int_bits[quant_layer]: - for layer in self.end_layer: - quant_max_val[layer]=float('-inf') - quant_min_val[layer]=float('inf') - self.act_int_bits[quant_layer] = self.act_int_bits[quant_layer]-1 - self.act_dec_bits[quant_layer] = self.act_dec_bits[quant_layer]+1 - for i in range(0,self.iterations): - for layer_no in range(0,len(self.start_layer)): - if layer_no==0: - net.forward(end=str(self.end_layer[layer_no])) - else: - net.forward(start=str(self.start_layer[layer_no]),end=str(self.end_layer[layer_no])) - if quant_layer_flag[self.end_layer[layer_no]]==1: - net.blobs[self.end_layer[layer_no]].data[:]=np.floor(net.blobs[self.end_layer[layer_no]].data*\ - (2**self.act_dec_bits[self.end_layer[layer_no]])) - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data>126]=127 - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data<-127]=-128 - net.blobs[self.end_layer[layer_no]].data[:]=net.blobs[self.end_layer[layer_no]].data/\ - (2**self.act_dec_bits[self.end_layer[layer_no]]) - layer_max = net.blobs[self.end_layer[layer_no]].data.max() - layer_min = net.blobs[self.end_layer[layer_no]].data.min() - if(layer_max>quant_max_val[self.end_layer[layer_no]]): - quant_max_val[self.end_layer[layer_no]]=layer_max - if(layer_minbest_accuracy: - best_int_bits = self.act_int_bits[quant_layer] - best_dec_bits = self.act_dec_bits[quant_layer] - best_accuracy = accuracy - print('Layer-'+quant_layer+' max: '+str(quant_max_val[quant_layer])+\ - 'min: '+str(quant_min_val[quant_layer])+' format: Q'+\ - str(self.act_int_bits[quant_layer])+'.'+str(self.act_dec_bits[quant_layer])+\ - ' accuracy: %.2f%%' %(acc.mean())) - self.act_int_bits[quant_layer] = best_int_bits - self.act_dec_bits[quant_layer] = best_dec_bits - print('Layer-'+quant_layer+' final format: Q'+str(self.act_int_bits[quant_layer])+\ - '.'+str(self.act_dec_bits[quant_layer])+ ' accuracy: %.2f%%' %(best_accuracy)) - - def quantize_bias_8bit(self,tolerance=0.001,search_range=3): - if self.gpu==True: - caffe.set_mode_gpu() - net = caffe.Net(self.model_file,self.quant_weight_file,caffe.TEST) - acc = np.zeros(self.iterations) - for i in range(0,self.iterations): - net.forward() - acc[i] = net.blobs[self.accuracy_layer].data*100 - target_accuracy = acc.mean() - print("Accuracy with quantized weights: %.2f%%" %(target_accuracy)) - for i in range(0,self.iterations): - for layer_no in range(0,len(self.start_layer)): - if layer_no==0: - net.forward(end=str(self.end_layer[layer_no])) - else: - net.forward(start=str(self.start_layer[layer_no]),end=str(self.end_layer[layer_no])) - if layer_no < len(self.start_layer)-1: # not quantizing accuracy layer - net.blobs[self.end_layer[layer_no]].data[:]=np.floor(net.blobs[self.end_layer[layer_no]].data*\ - (2**self.act_dec_bits[self.end_layer[layer_no]])) - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data>126]=127 - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data<-127]=-128 - net.blobs[self.end_layer[layer_no]].data[:]=net.blobs[self.end_layer[layer_no]].data/\ - (2**self.act_dec_bits[self.end_layer[layer_no]]) - acc[i] = net.blobs[self.accuracy_layer].data*100 - target_accuracy = acc.mean() - print("Accuracy with quantized weights and activations: %.2f%%" %(target_accuracy)) - input_of={} - for i in range (1,len(self.end_layer)): - input_of[self.end_layer[i]]=self.end_layer[i-1] - for layer_name in self.conv_layer+self.ip_layer: - mac_dec_bits = self.wt_dec_bits[layer_name]+self.act_dec_bits[input_of[layer_name]] - bias_max = net.params[layer_name][1].data.max() - bias_min = net.params[layer_name][1].data.min() - int_bits = int(np.ceil(np.log2(max(abs(bias_min),abs(bias_max))))) - dec_bits = 7-int_bits - max_int_bits = int_bits-search_range - if(dec_bits>mac_dec_bits): - dec_bits=mac_dec_bits - int_bits=7-dec_bits - max_int_bits=int_bits #can't increase dec_bits any more as they will be shifted right anyway - print('Layer: '+ layer_name + ' biases max: '+str(bias_max)+' min: '+str(bias_min)+\ - ' Format: Q'+str(int_bits)+'.'+str(dec_bits)) - net.params[layer_name][1].data[:]=np.round(net.params[layer_name][1].data*(2**dec_bits))/(2**dec_bits) - for i in range(0,self.iterations): - for layer_no in range(0,len(self.start_layer)): - if layer_no==0: - net.forward(end=str(self.end_layer[layer_no])) - else: - net.forward(start=str(self.start_layer[layer_no]),end=str(self.end_layer[layer_no])) - if layer_no < len(self.start_layer)-1: # not quantizing accuracy layer - net.blobs[self.end_layer[layer_no]].data[:]=np.floor(net.blobs[self.end_layer[layer_no]].data*\ - (2**self.act_dec_bits[self.end_layer[layer_no]])) - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data>126]=127 - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data<-127]=-128 - net.blobs[self.end_layer[layer_no]].data[:]=net.blobs[self.end_layer[layer_no]].data/\ - (2**self.act_dec_bits[self.end_layer[layer_no]]) - acc[i] = net.blobs[self.accuracy_layer].data*100 - accuracy = acc.mean() - print("Accuracy: %.2f%%" %(accuracy)) - best_int_bits = int_bits - best_dec_bits = dec_bits - best_accuracy = accuracy - while target_accuracy-accuracy>tolerance and int_bits>max_int_bits: - int_bits = int_bits-1 - dec_bits = dec_bits+1 - net.copy_from(self.quant_weight_file) - net.params[layer_name][1].data[:]=np.round(net.params[layer_name][1].data*(2**dec_bits)) - net.params[layer_name][1].data[net.params[layer_name][1].data>126]=127 - net.params[layer_name][1].data[net.params[layer_name][1].data<-127]=-128 - net.params[layer_name][1].data[:]=net.params[layer_name][1].data/(2**dec_bits) - for i in range(0,self.iterations): - for layer_no in range(0,len(self.start_layer)): - if layer_no==0: - net.forward(end=str(self.end_layer[layer_no])) - else: - net.forward(start=str(self.start_layer[layer_no]),end=str(self.end_layer[layer_no])) - if layer_no < len(self.start_layer)-1: # not quantizing accuracy layer - net.blobs[self.end_layer[layer_no]].data[:]=np.floor(net.blobs[self.end_layer[layer_no]].data*\ - (2**self.act_dec_bits[self.end_layer[layer_no]])) - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data>126]=127 - net.blobs[self.end_layer[layer_no]].data[net.blobs[self.end_layer[layer_no]].data<-127]=-128 - net.blobs[self.end_layer[layer_no]].data[:]=net.blobs[self.end_layer[layer_no]].data/\ - (2**self.act_dec_bits[self.end_layer[layer_no]]) - acc[i] = net.blobs[self.accuracy_layer].data*100 - accuracy = acc.mean() - print('Format Q'+str(int_bits)+'.'+str(dec_bits)+' Accuracy: %.2f%%' %(accuracy)) - if accuracy>best_accuracy: - best_int_bits = int_bits - best_dec_bits = dec_bits - best_accuracy = accuracy - self.bias_int_bits[layer_name] = best_int_bits - self.bias_dec_bits[layer_name] = best_dec_bits - self.bias_lshift[layer_name]=mac_dec_bits-best_dec_bits - self.act_rshift[layer_name]=mac_dec_bits-self.act_dec_bits[layer_name] - net.copy_from(self.quant_weight_file) - net.params[layer_name][1].data[:]=np.round(net.params[layer_name][1].data*(2**best_dec_bits)) - net.params[layer_name][1].data[net.params[layer_name][1].data>126]=127 - net.params[layer_name][1].data[net.params[layer_name][1].data<-127]=-128 - net.params[layer_name][1].data[:]=net.params[layer_name][1].data/(2**best_dec_bits) - print('Final '+layer_name+ ' biases format Q'+str(best_int_bits)+'.'+str(best_dec_bits)+\ - ' Accuracy: %.2f%%' %(best_accuracy)) - net.save(self.quant_weight_file) - -if __name__ == '__main__': - - parser = argparse.ArgumentParser() - parser.add_argument('--gpu', dest='gpu', action='store_true', - help='flag to enable gpu for quantization sweeps') - parser.set_defaults(gpu=False) - parser.add_argument('--accuracy', type=str, default="accuracy", - help='target accuracy') - parser.add_argument('--iterations', type=int, default=100, - help='number of iterations: data_size/batch_size') - parser.add_argument('--tolerance', type=float, default=0.001, - help='accuracy tolerance') - parser.add_argument('--model', type=str, default=\ - "models/cifar10_m4_train_test.prototxt", - help='caffe model definition (.prototxt)') - parser.add_argument('--weights', type=str, default=\ - "models/cifar10_m4_iter_70000.caffemodel.h5", - help='caffe model weights (.caffemodel)') - parser.add_argument('--save', type=str, default=\ - "models/cifar10_m4.pkl", - help='save quantization parameters and connectivity') - - cmd_args, _ = parser.parse_known_args() - - gpu_flag = cmd_args.gpu - model_file=cmd_args.model - weight_file=cmd_args.weights - iterations=cmd_args.iterations - tolerance=cmd_args.tolerance - target_accuracy_layer=cmd_args.accuracy - - my_model=Caffe_Quantizer(model_file,weight_file,iterations,accuracy_layer=target_accuracy_layer,gpu=gpu_flag) - my_model.get_layer_info() - my_model.get_graph_connectivity() - my_model.run_full_network() - #First quantize weights to 8 bits - my_model.quantize_wts_8bit() - #Then quantize activations to 8 bits - my_model.quantize_activations_8bit() - #Quantize biases to 8 bits based on the quantization outputs of weights and activations - my_model.quantize_bias_8bit() - my_model.run_quantized_network() - - my_model.save_quant_params(cmd_args.save) - #To load the parameters use the following: - #my_model.load_quant_params('mymodel.p') - - #Print dataformats - print('Input: '+my_model.data_layer+' Q'+str(my_model.act_int_bits[my_model.data_layer])+'.'+\ - str(my_model.act_dec_bits[my_model.data_layer])+'(scaling factor:'+\ - str(2**(my_model.act_dec_bits[my_model.data_layer]))+')') - for layer in my_model.conv_layer+my_model.ip_layer: - print('Layer: '+layer+' Q'+str(my_model.act_int_bits[layer])+'.'+str(my_model.act_dec_bits[layer])+\ - ' (scaling factor:'+str(2**(my_model.act_dec_bits[layer]))+') Wts: Q'+\ - str(my_model.wt_int_bits[layer])+'.'+str(my_model.wt_dec_bits[layer])+\ - ' (scaling factor:'+str(2**(my_model.wt_dec_bits[layer]))+') Biases: Q'+\ - str(my_model.bias_int_bits[layer])+'.'+str(my_model.bias_dec_bits[layer])+\ - '(scaling factor:'+str(2**(my_model.bias_dec_bits[layer]))+')') - - #Print data shifts to be used by ML kernels - for layer in my_model.conv_layer+my_model.ip_layer: - print('Layer: '+layer+' bias left shift: '+str(my_model.bias_lshift[layer])+\ - ' act_rshift: '+str(my_model.act_rshift[layer])) - diff --git a/ml/cmsisnn/nn_run_all.sh b/ml/cmsisnn/nn_run_all.sh deleted file mode 100755 index ba238efcf..000000000 --- a/ml/cmsisnn/nn_run_all.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env sh -# This file is part of the OpenMV project. -# -# Copyright (c) 2013-2019 Ibrahim Abdelkader -# Copyright (c) 2013-2019 Kwabena W. Agyeman -# -# This work is licensed under the MIT license, see the file LICENSE for details. - -if [ -z $1 ]; then - echo "Usage : nn_run_all.sh model_name" - exit 1 -fi -MODEL=${1} -set -v -python2 nn_quantizer.py --model models/${MODEL}/${MODEL}_train_test.prototxt --weights models/${MODEL}/${MODEL}_iter_*.caffemodel --save models/${MODEL}/${MODEL}.pkl --gpu -python2 nn_convert.py --model models/${MODEL}/${MODEL}.pkl --mean caffe/examples/${MODEL}/mean.binaryproto --output models/${MODEL}/${MODEL}.network diff --git a/scripts/examples/25-Machine-Learning/nn_cifar10.py b/scripts/examples/25-Machine-Learning/nn_cifar10.py deleted file mode 100644 index 24e401f2b..000000000 --- a/scripts/examples/25-Machine-Learning/nn_cifar10.py +++ /dev/null @@ -1,33 +0,0 @@ -# CIFAR10 Example -import sensor, image, time, os, nn - -sensor.reset() # Reset and initialize the sensor. -sensor.set_contrast(3) -sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 -sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) -sensor.set_windowing((128, 128)) # Set 128x128 window. -sensor.skip_frames(time=1000) -sensor.set_auto_gain(False) -sensor.set_auto_exposure(False) - -# Load cifar10 network -net = nn.load('/cifar10.network') -# Faster, smaller and less accurate. -#net = nn.load('/cifar10_fast.network') -labels = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] - -clock = time.clock() # Create a clock object to track the FPS. -while(True): - clock.tick() # Update the FPS clock. - img = sensor.snapshot() # Take a picture and return the image. - out = net.forward(img) - max_idx = out.index(max(out)) - score = int(out[max_idx]*100) - if (score < 70): - score_str = "??:??%" - else: - score_str = "%s:%d%% "%(labels[max_idx], score) - img.draw_string(0, 0, score_str, color=(255, 0, 0)) - - print(clock.fps()) # Note: OpenMV Cam runs about half as fast when connected - # to the IDE. The FPS should increase once disconnected. diff --git a/scripts/examples/25-Machine-Learning/nn_cifar10_search_just_center.py b/scripts/examples/25-Machine-Learning/nn_cifar10_search_just_center.py deleted file mode 100644 index fd94308ba..000000000 --- a/scripts/examples/25-Machine-Learning/nn_cifar10_search_just_center.py +++ /dev/null @@ -1,53 +0,0 @@ -# CIFAR-10 Search Just Center Example -# -# CIFAR is a convolutional nueral network designed to classify it's field of view into several -# different object types and works on RGB video data. -# -# In this example we slide the LeNet detector window over the image and get a list of activations -# where there might be an object. Note that use a CNN with a sliding window is extremely compute -# expensive so for an exhaustive search do not expect the CNN to be real-time. - -import sensor, image, time, os, nn - -sensor.reset() # Reset and initialize the sensor. -sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE) -sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) -sensor.set_windowing((128, 128)) # Set 128x128 window. -sensor.skip_frames(time=750) # Don't let autogain run very long. -sensor.set_auto_gain(False) # Turn off autogain. -sensor.set_auto_exposure(False) # Turn off whitebalance. - -# Load cifar10 network (You can get the network from OpenMV IDE). -net = nn.load('/cifar10.network') -# Faster, smaller and less accurate. -# net = nn.load('/cifar10_fast.network') -labels = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] - -clock = time.clock() -while(True): - clock.tick() - - img = sensor.snapshot() - - # net.search() will search an roi in the image for the network (or the whole image if the roi is not - # specified). At each location to look in the image if one of the classifier outputs is larger than - # threshold the location and label will be stored in an object list and returned. At each scale the - # detection window is moved around in the ROI using x_overlap (0-1) and y_overlap (0-1) as a guide. - # If you set the overlap to 0.5 then each detection window will overlap the previous one by 50%. Note - # the computational work load goes WAY up the more overlap. Finally, for mult-scale matching after - # sliding the network around in the x/y dimensions the detection window will shrink by scale_mul (0-1) - # down to min_scale (0-1). For example, if scale_mul is 0.5 the detection window will shrink by 50%. - # Note that at a lower scale there's even more area to search if x_overlap and y_overlap are small... - # contrast_threshold skips running the CNN in areas that are flat. - - # Setting x_overlap=-1 forces the window to stay centered in the ROI in the x direction always. If - # y_overlap is not -1 the method will search in all vertical positions. - - # Setting y_overlap=-1 forces the window to stay centered in the ROI in the y direction always. If - # x_overlap is not -1 the method will serach in all horizontal positions. - - for obj in net.search(img, threshold=0.6, min_scale=0.4, scale_mul=0.8, \ - x_overlap=-1, y_overlap=-1, contrast_threshold=0.5): - print("Detected %s - Confidence %f%%" % (labels[obj.index()], obj.value())) - img.draw_rectangle(obj.rect(), color=(255, 0, 0)) - print(clock.fps()) diff --git a/scripts/examples/25-Machine-Learning/nn_cifar10_search_whole_window.py b/scripts/examples/25-Machine-Learning/nn_cifar10_search_whole_window.py deleted file mode 100644 index 10ebbbc2f..000000000 --- a/scripts/examples/25-Machine-Learning/nn_cifar10_search_whole_window.py +++ /dev/null @@ -1,47 +0,0 @@ -# CIFAR-10 Search Whole Window Example -# -# CIFAR is a convolutional nueral network designed to classify it's field of view into several -# different object types and works on RGB video data. -# -# In this example we slide the LeNet detector window over the image and get a list of activations -# where there might be an object. Note that use a CNN with a sliding window is extremely compute -# expensive so for an exhaustive search do not expect the CNN to be real-time. - -import sensor, image, time, os, nn - -sensor.reset() # Reset and initialize the sensor. -sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE) -sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) -sensor.set_windowing((128, 128)) # Set 128x128 window. -sensor.skip_frames(time=750) # Don't let autogain run very long. -sensor.set_auto_gain(False) # Turn off autogain. -sensor.set_auto_exposure(False) # Turn off whitebalance. - -# Load cifar10 network (You can get the network from OpenMV IDE). -net = nn.load('/cifar10.network') -# Faster, smaller and less accurate. -# net = nn.load('/cifar10_fast.network') -labels = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] - -clock = time.clock() -while(True): - clock.tick() - - img = sensor.snapshot() - - # net.search() will search an roi in the image for the network (or the whole image if the roi is not - # specified). At each location to look in the image if one of the classifier outputs is larger than - # threshold the location and label will be stored in an object list and returned. At each scale the - # detection window is moved around in the ROI using x_overlap (0-1) and y_overlap (0-1) as a guide. - # If you set the overlap to 0.5 then each detection window will overlap the previous one by 50%. Note - # the computational work load goes WAY up the more overlap. Finally, for mult-scale matching after - # sliding the network around in the x/y dimensions the detection window will shrink by scale_mul (0-1) - # down to min_scale (0-1). For example, if scale_mul is 0.5 the detection window will shrink by 50%. - # Note that at a lower scale there's even more area to search if x_overlap and y_overlap are small... - # contrast_threshold skips running the CNN in areas that are flat. - - for obj in net.search(img, threshold=0.6, min_scale=0.5, scale_mul=0.5, \ - x_overlap=0.5, y_overlap=0.5, contrast_threshold=0.5): - print("Detected %s - Confidence %f%%" % (labels[obj.index()], obj.value())) - img.draw_rectangle(obj.rect(), color=(255, 0, 0)) - print(clock.fps()) diff --git a/scripts/examples/25-Machine-Learning/nn_haar_smile_detection.py b/scripts/examples/25-Machine-Learning/nn_haar_smile_detection.py deleted file mode 100644 index f94d29be2..000000000 --- a/scripts/examples/25-Machine-Learning/nn_haar_smile_detection.py +++ /dev/null @@ -1,37 +0,0 @@ -# Simle detection using Haar Cascade + CNN. -import sensor, time, image, os, nn - -sensor.reset() # Reset and initialize the sensor. -sensor.set_contrast(2) -sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 -sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) -sensor.skip_frames(time=2000) -sensor.set_auto_gain(False) - -# Load smile detection network -net = nn.load('/smile.network') - -# Load Face Haar Cascade -face_cascade = image.HaarCascade("frontalface", stages=25) -print(face_cascade) - -# FPS clock -clock = time.clock() -while (True): - clock.tick() - - # Capture snapshot - img = sensor.snapshot() - - # Find faces. - objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25) - - # Detect smiles - for r in objects: - # Resize and center detection area - r = [r[0]+10, r[1]+25, int(r[2]*0.70), int(r[2]*0.70)] - img.draw_rectangle(r) - out = net.forward(img, roi=r, softmax=True) - img.draw_string(r[0], r[1], ':)' if (out[0] > 0.8) else ':(', color=(255), scale=2) - - print(clock.fps()) diff --git a/scripts/examples/25-Machine-Learning/nn_lenet.py b/scripts/examples/25-Machine-Learning/nn_lenet.py deleted file mode 100644 index 4d1927e48..000000000 --- a/scripts/examples/25-Machine-Learning/nn_lenet.py +++ /dev/null @@ -1,31 +0,0 @@ -# LetNet Example -import sensor, image, time, os, nn - -sensor.reset() # Reset and initialize the sensor. -sensor.set_contrast(3) -sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE) -sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) -sensor.set_windowing((128, 128)) # Set 128x128 window. -sensor.skip_frames(time=100) -sensor.set_auto_gain(False) -sensor.set_auto_exposure(False) - -# Load lenet network -net = nn.load('/lenet.network') -labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] - -clock = time.clock() # Create a clock object to track the FPS. -while(True): - clock.tick() # Update the FPS clock. - img = sensor.snapshot() # Take a picture and return the image. - out = net.forward(img.copy().binary([(150, 255)], invert=True)) - max_idx = out.index(max(out)) - score = int(out[max_idx]*100) - if (score < 70): - score_str = "??:??%" - else: - score_str = "%s:%d%% "%(labels[max_idx], score) - img.draw_string(0, 0, score_str) - - print(clock.fps()) # Note: OpenMV Cam runs about half as fast when connected - # to the IDE. The FPS should increase once disconnected. diff --git a/scripts/examples/25-Machine-Learning/nn_lenet_search_just_center.py b/scripts/examples/25-Machine-Learning/nn_lenet_search_just_center.py deleted file mode 100644 index c5910528d..000000000 --- a/scripts/examples/25-Machine-Learning/nn_lenet_search_just_center.py +++ /dev/null @@ -1,51 +0,0 @@ -# LeNet Search Just Center Example -# -# LeNet is a convolutional nueral network designed to classify it's field of view into digits 0-9. -# -# In this example we slide the LeNet detector window over the image and get a list of activations -# where there might be an object. Note that use a CNN with a sliding window is extremely compute -# expensive so for an exhaustive search do not expect the CNN to be real-time. - -import sensor, image, time, os, nn - -sensor.reset() # Reset and initialize the sensor. -sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE) -sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) -sensor.set_windowing((128, 128)) # Set 128x128 window. -sensor.skip_frames(time=500) # Don't let autogain run very long. -sensor.set_auto_gain(False) # Turn off autogain. -sensor.set_auto_exposure(False) # Turn off whitebalance. - -# Load lenet network (You can get the network from OpenMV IDE). -net = nn.load('/lenet.network') -labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] - -clock = time.clock() -while(True): - clock.tick() - - img = sensor.snapshot() - tmp_img = img.copy().binary([(150, 255)], invert=True) - - # net.search() will search an roi in the image for the network (or the whole image if the roi is not - # specified). At each location to look in the image if one of the classifier outputs is larger than - # threshold the location and label will be stored in an object list and returned. At each scale the - # detection window is moved around in the ROI using x_overlap (0-1) and y_overlap (0-1) as a guide. - # If you set the overlap to 0.5 then each detection window will overlap the previous one by 50%. Note - # the computational work load goes WAY up the more overlap. Finally, for mult-scale matching after - # sliding the network around in the x/y dimensions the detection window will shrink by scale_mul (0-1) - # down to min_scale (0-1). For example, if scale_mul is 0.5 the detection window will shrink by 50%. - # Note that at a lower scale there's even more area to search if x_overlap and y_overlap are small... - # contrast_threshold skips running the CNN in areas that are flat. - - # Setting x_overlap=-1 forces the window to stay centered in the ROI in the x direction always. If - # y_overlap is not -1 the method will search in all vertical positions. - - # Setting y_overlap=-1 forces the window to stay centered in the ROI in the y direction always. If - # x_overlap is not -1 the method will serach in all horizontal positions. - - for obj in net.search(tmp_img, threshold=0.8, min_scale=0.4, scale_mul=0.8, \ - x_overlap=-1, y_overlap=-1, contrast_threshold=0.5): - print("Detected %s - Confidence %f%%" % (labels[obj.index()], obj.value())) - img.draw_rectangle(obj.rect()) - print(clock.fps()) diff --git a/scripts/examples/25-Machine-Learning/nn_lenet_search_whole_window.py b/scripts/examples/25-Machine-Learning/nn_lenet_search_whole_window.py deleted file mode 100644 index 268124773..000000000 --- a/scripts/examples/25-Machine-Learning/nn_lenet_search_whole_window.py +++ /dev/null @@ -1,45 +0,0 @@ -# LeNet Search Whole Window Example -# -# LeNet is a convolutional nueral network designed to classify it's field of view into digits 0-9. -# -# In this example we slide the LeNet detector window over the image and get a list of activations -# where there might be an object. Note that use a CNN with a sliding window is extremely compute -# expensive so for an exhaustive search do not expect the CNN to be real-time. - -import sensor, image, time, os, nn - -sensor.reset() # Reset and initialize the sensor. -sensor.set_pixformat(sensor.GRAYSCALE) # Set pixel format to RGB565 (or GRAYSCALE) -sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) -sensor.set_windowing((128, 128)) # Set 128x128 window. -sensor.skip_frames(time=500) # Don't let autogain run very long. -sensor.set_auto_gain(False) # Turn off autogain. -sensor.set_auto_exposure(False) # Turn off whitebalance. - -# Load lenet network (You can get the network from OpenMV IDE). -net = nn.load('/lenet.network') -labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] - -clock = time.clock() -while(True): - clock.tick() - - img = sensor.snapshot() - tmp_img = img.copy().binary([(150, 255)], invert=True) - - # net.search() will search an roi in the image for the network (or the whole image if the roi is not - # specified). At each location to look in the image if one of the classifier outputs is larger than - # threshold the location and label will be stored in an object list and returned. At each scale the - # detection window is moved around in the ROI using x_overlap (0-1) and y_overlap (0-1) as a guide. - # If you set the overlap to 0.5 then each detection window will overlap the previous one by 50%. Note - # the computational work load goes WAY up the more overlap. Finally, for mult-scale matching after - # sliding the network around in the x/y dimensions the detection window will shrink by scale_mul (0-1) - # down to min_scale (0-1). For example, if scale_mul is 0.5 the detection window will shrink by 50%. - # Note that at a lower scale there's even more area to search if x_overlap and y_overlap are small... - # contrast_threshold skips running the CNN in areas that are flat. - - for obj in net.search(tmp_img, threshold=0.9, min_scale=0.5, scale_mul=0.5, \ - x_overlap=0.5, y_overlap=0.5, contrast_threshold=0.5): - print("Detected %s - Confidence %f%%" % (labels[obj.index()], obj.value())) - img.draw_rectangle(obj.rect()) - print(clock.fps())