tod enhanced examples

pull/9563/head
yoni 4 years ago
parent 201c5ff4ee
commit 1f66e59648

@ -1,24 +0,0 @@
CONVERTER="../../../../../mindspore/lite/build/tools/converter/converter_lite"
if [ ! -f "$CONVERTER" ]; then
if ! command -v converter_lite &> /dev/null
then
echo "converter_lite could not be found in MindSpore build directory nor in system path"
exit
else
CONVERTER=converter_lite
fi
fi
echo "============Exporting=========="
if [ -n "$1" ]; then
DOCKER_IMG=$1
docker run -w $PWD --runtime=nvidia -v /home/$USER:/home/$USER --privileged=true ${DOCKER_IMG} /bin/bash -c "python lenet_export.py; chmod 444 lenet_tod.mindir; rm -rf __pycache__"
else
echo "MindSpore docker was not provided, attempting to run locally"
python lenet_export.py
fi
echo "============Converting========="
$CONVERTER --fmk=MINDIR --trainModel=true --modelFile=lenet_tod.mindir --outputFile=lenet_tod

@ -1,82 +0,0 @@
#!/bin/bash
display_usage() {
echo -e "\nUsage: prepare_and_run.sh dataset_path [mindspore_docker] [release.tar.gz]\n"
}
if [ -n "$1" ]; then
MNIST_DATA_PATH=$1
else
echo "MNIST Dataset directory path was not provided"
display_usage
exit 0
fi
if [ -n "$2" ]; then
DOCKER=$2
else
DOCKER=""
#echo "MindSpore docker was not provided"
#display_usage
#exit 0
fi
if [ -n "$3" ]; then
TARBALL=$3
else
if [ -f ../../../../output/mindspore-lite-*-runtime-arm64-cpu-train.tar.gz ]; then
TARBALL="../../../../output/mindspore-lite-*-runtime-arm64-cpu-train.tar.gz"
else
echo "release.tar.gz was not found"
display_usage
exit 0
fi
fi
# Prepare the model
cd model/
rm -f *.ms
./prepare_model.sh $DOCKER
cd -
# Copy the .ms model to the package folder
rm -rf package
mkdir -p package/model
cp model/*.ms package/model
# Copy the running script to the package
cp scripts/train.sh package/
cp scripts/eval.sh package/
# Copy the shared MindSpore ToD library
tar -xzvf ${TARBALL} --wildcards --no-anchored libmindspore-lite.so
tar -xzvf ${TARBALL} --wildcards --no-anchored include
mv mindspore-*/lib package/
mkdir msl
mv mindspore-*/* msl/
rm -rf mindspore-*
# Copy the dataset to the package
cp -r ${MNIST_DATA_PATH} package/dataset
# Compile program
make TARGET=arm64
# Copy the executable to the package
mv bin package/
# Push the folder to the device
adb push package /data/local/tmp/
echo "Training on Device"
adb shell < scripts/run_train.sh
echo
echo "Load trained model and evaluate accuracy"
adb shell < scripts/run_eval.sh
echo
#rm -rf src/*.o package model/__pycache__ model/*.ms
#./prepare_and_run.sh /opt/share/dataset/mnist mindspore_dev:5

@ -1,2 +0,0 @@
cd /data/local/tmp/package
/system/bin/sh eval.sh

@ -1,2 +0,0 @@
cd /data/local/tmp/package
/system/bin/sh train.sh

@ -0,0 +1,41 @@
BASE_DIR=$(realpath ../../../../)
APP:=bin/net_runner
MSLIB:=mindspore-lite
MSDIR:=$(realpath package-$(TARGET)/lib)
SRC:=src/net_runner.cc src/dataset.cc
OBJ:=$(SRC:.cc=.o)
CFLAGS := -Ofast -std=c++17 \
-I . \
-I ./msl \
-I ./msl/third_party/flatbuffers/include
ifeq ($(TARGET),arm64)
CXX := ${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
CFLAGS += --target=aarch64-none-linux-android21 --gcc-toolchain=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fdata-sections -ffunction-sections
LDFLAGS := --target=aarch64-none-linux-android21 --gcc-toolchain=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Wl,--gc-sections
LDFLAGS += -L$(MSDIR) -l$(MSLIB) -pthread -llog -latomic -lm
else
CFLAGS += -g
LDFLAGS := -L$(MSDIR) -l$(MSLIB) -lpthread -Wl,-rpath,$(MSDIR)
endif
LD := ${CXX}
all:$(APP)
$(APP): $(OBJ) $(MSDIR)/lib$(MSLIB).so
@mkdir -p bin
$(LD) $(OBJ) $(LDFLAGS) -o $@
clean:
rm -rf src/*.o bin/
mrproper:
rm -rf package* msl src/*.o bin/ model/*.mindir model/*.ms model/*.so model/converter_lite
%.o:%.cc
$(CXX) $(CFLAGS) -c $< -o $@

@ -21,7 +21,7 @@ LeNet is a very simple network which is composed of only 5 layers, 2 of which ar
# Dataset
In this example we use the MNIST dataset of handwritten digits as published in [THE MNIST DATABASE](<http://yann.lecun.com/exdb/mnist/>)
In this example we use the MNIST dataset of handwritten digits as published in [THE MNIST DATABASE](http://yann.lecun.com/exdb/mnist/)
- Dataset size52.4M60,000 28*28 in 10 classes
- Test10,000 images
@ -31,7 +31,7 @@ In this example we use the MNIST dataset of handwritten digits as published in [
- The dataset directory structure is as follows:
```python
```text
mnist/
├── test
│   ├── t10k-images-idx3-ubyte
@ -54,15 +54,16 @@ mnist/
After installing all the above mentioned, the script in the home directory could be run with the following arguments:
```python
sh ./prepare_and_run.sh DATASET_PATH [MINDSPORE_DOCKER] [RELEASE.tar.gz]
```bash
sh ./prepare_and_run.sh -D DATASET_PATH [-d MINDSPORE_DOCKER] [-r RELEASE.tar.gz] [-t arm64|x86]
```
where:
- DATASET_PATH is the path to the [dataset](#dataset),
- MINDSPORE_DOCKER is the image name of the docker that runs [MindSpore](#environment-requirements). If not provided MindSpore will be run locally
- and REALEASE.tar.gz is a pointer to the MindSpore ToD release tar ball. If not provided, the script will attempt to find MindSpore ToD compilation output.
- REALEASE.tar.gz is a pointer to the MindSpore ToD release tar ball. If not provided, the script will attempt to find MindSpore ToD compilation output
- target is defaulted to arm64, i.e., on-device. If x86 is provided, the demo will be run locally. Note that infrastructure is not optimized for device
# Script Detailed Description

@ -14,7 +14,6 @@
# ============================================================================
"""lenet_export."""
import sys
from mindspore import context, Tensor
import mindspore.common.dtype as mstype
from mindspore.train.serialization import export
@ -22,15 +21,14 @@ from lenet import LeNet5
import numpy as np
from train_utils import TrainWrap
sys.path.append('../../../cv/lenet/src/')
n = LeNet5()
n.set_train()
context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU", save_graphs=False)
batch_size = 32
x = Tensor(np.ones((batch_size, 1, 32, 32)), mstype.float32)
label = Tensor(np.zeros([batch_size, 10]).astype(np.float32))
BATCH_SIZE = 32
x = Tensor(np.ones((BATCH_SIZE, 1, 32, 32)), mstype.float32)
label = Tensor(np.zeros([BATCH_SIZE, 10]).astype(np.float32))
net = TrainWrap(n)
export(net, x, label, file_name="lenet_tod.mindir", file_format='MINDIR')

@ -0,0 +1,32 @@
#!/bin/bash
echo "============Exporting=========="
if [ -n "$1" ]; then
DOCKER_IMG=$1
docker run -w $PWD --runtime=nvidia -v /home/$USER:/home/$USER --privileged=true ${DOCKER_IMG} /bin/bash -c "PYTHONPATH=../../../../../model_zoo/official/cv/lenet/src python lenet_export.py; chmod 444 lenet_tod.mindir; rm -rf __pycache__"
else
echo "MindSpore docker was not provided, attempting to run locally"
PYTHONPATH=../../../../../model_zoo/official/cv/lenet/src python lenet_export.py
fi
CONVERTER="../../../build/tools/converter/converter_lite"
if [ ! -f "$CONVERTER" ]; then
if ! command -v converter_lite &> /dev/null
then
tar -xzf ../../../../../output/mindspore-lite-*-converter-ubuntu-train.tar.gz --strip-components 2 --wildcards --no-anchored converter_lite libmindspore_gvar.so
if [ -f ./converter_lite ]; then
CONVERTER=./converter_lite
else
echo "converter_lite could not be found in MindSpore build directory nor in system path"
exit 1
fi
else
CONVERTER=converter_lite
fi
fi
echo "============Converting========="
LD_LIBRARY_PATH=./ $CONVERTER --fmk=MINDIR --trainModel=true --modelFile=lenet_tod.mindir --outputFile=lenet_tod

@ -22,13 +22,13 @@ def TrainWrap(net, loss_fn=None, optimizer=None, weights=None):
TrainWrap
"""
if loss_fn is None:
loss_fn = nn.SoftmaxCrossEntropyWithLogits()
loss_fn = nn.SoftmaxCrossEntropyWithLogits(reduction='mean')
loss_net = nn.WithLossCell(net, loss_fn)
loss_net.set_train()
if weights is None:
weights = ParameterTuple(net.trainable_params())
if optimizer is None:
optimizer = nn.Adam(weights, learning_rate=1e-3, beta1=0.9, beta2=0.999, eps=1e-8, use_locking=False,
optimizer = nn.Adam(weights, learning_rate=1e-2, beta1=0.9, beta2=0.999, eps=1e-8, use_locking=False,
use_nesterov=False, weight_decay=0.0, loss_scale=1.0)
train_net = nn.TrainOneStepCell(loss_net, optimizer)
return train_net

@ -0,0 +1,116 @@
#!/bin/bash
display_usage()
{
echo -e "\nUsage: prepare_and_run.sh -D dataset_path [-d mindspore_docker] [-r release.tar.gz] [-t arm64|x86]\n"
}
checkopts()
{
TARGET="arm64"
DOCKER=""
MNIST_DATA_PATH=""
while getopts 'D:d:r:t:' opt
do
OPTARG=$(echo ${OPTARG} | tr '[A-Z]' '[a-z]')
case "${opt}" in
D)
MNIST_DATA_PATH=$OPTARG
;;
d)
DOCKER=$OPTARG
;;
t)
if [ "$OPTARG" == "arm64" ] || [ "$OPTARG" == "x86" ]; then
TARGET=$OPTARG
else
echo "No such target " $OPTARG
display_usage
exit 1
fi
;;
r)
TARBALL=$OPTARG
;;
*)
echo "Unknown option ${opt}!"
display_usage
exit 1
esac
done
}
checkopts "$@"
if [ "$MNIST_DATA_PATH" == "" ]; then
echo "MNIST Dataset directory path was not provided"
display_usage
exit 1
fi
if [ "$TARBALL" == "" ]; then
file=$(ls ../../../../output/mindspore-lite-*-runtime-${TARGET}-cpu-train.tar.gz)
if [ -f ${file} ]; then
TARBALL=${file}
else
echo "release.tar.gz was not found"
display_usage
exit 1
fi
fi
# Prepare the model
cd model/ || exit 1
rm -f *.ms
./prepare_model.sh $DOCKER || exit 1
cd ../
# Copy the .ms model to the package folder
PACKAGE=package-${TARGET}
rm -rf ${PACKAGE}
mkdir -p ${PACKAGE}/model
cp model/*.ms ${PACKAGE}/model
# Copy the running script to the package
cp scripts/*.sh ${PACKAGE}/
# Copy the shared MindSpore ToD library
tar -xzf ${TARBALL} --wildcards --no-anchored libmindspore-lite.so
tar -xzf ${TARBALL} --wildcards --no-anchored include
mv mindspore-*/lib ${PACKAGE}/
rm -rf msl
mkdir msl
mv mindspore-*/* msl/
rm -rf mindspore-*
# Copy the dataset to the package
cp -r ${MNIST_DATA_PATH} ${PACKAGE}/dataset
echo "==========Compiling============"
make TARGET=${TARGET}
# Copy the executable to the package
mv bin ${PACKAGE}/ || exit 1
if [ "${TARGET}" == "arm64" ]; then
echo "=======Pushing to device======="
adb push ${PACKAGE} /data/local/tmp/
echo "========Training on Device====="
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh train.sh"
echo
echo "===Evaluating trained Model====="
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh eval.sh"
echo
else
cd ${PACKAGE} || exit 1
echo "======Training Locally========="
./train.sh
echo "===Evaluating trained Model====="
./eval.sh
cd ..
fi

@ -15,5 +15,4 @@
# ============================================================================
# an simple tutorial as follows, more parameters can be setting
DATA_PATH=$1
LD_LIBRARY_PATH=./lib/ bin/net_runner -f model/lenet_tod_trained_3000.ms -e 0 -d dataset

@ -15,7 +15,4 @@
# ============================================================================
# an simple tutorial as follows, more parameters can be setting
script_self=$(readlink -f "$0")
self_path=$(dirname "${script_self}")
DATA_PATH=$1
LD_LIBRARY_PATH=./lib/ bin/net_runner -f model/lenet_tod.ms -e 3000 -d dataset

@ -72,11 +72,8 @@ int DataSet::Init(const std::string &data_base_directory, database_type type) {
}
void DataSet::InitializeMNISTDatabase(std::string dpath) {
// int total_data = 0;
num_of_classes_ = 10;
// total_data +=
ReadMNISTFile(dpath + "/train/train-images-idx3-ubyte", dpath + "/train/train-labels-idx1-ubyte", &train_data_);
// total_data +=
ReadMNISTFile(dpath + "/test/t10k-images-idx3-ubyte", dpath + "/test/t10k-labels-idx1-ubyte", &test_data_);
}
@ -152,49 +149,3 @@ int DataSet::ReadMNISTFile(const std::string &ifile_name, const std::string &lfi
}
return number_of_labels;
}
std::vector<FileTuple> DataSet::ReadFileList(std::string dpath) {
std::vector<FileTuple> vec;
std::ifstream ifs(dpath + "/file_list.txt");
std::string file_name;
if (ifs.is_open()) {
int label;
while (!ifs.eof()) {
ifs >> label >> file_name;
vec.push_back(make_tuple(label, file_name));
}
}
return vec;
}
std::vector<FileTuple> DataSet::ReadDir(const std::string dpath) {
std::filesystem::directory_iterator dir(dpath);
std::vector<FileTuple> vec;
LabelId label_id;
int class_id = 0;
int class_label;
for (const auto p : dir) {
if (p.is_directory()) {
std::string path = p.path().stem().string();
auto label = label_id.find(path);
if (label == label_id.end()) {
label_id[path] = class_id;
class_label = class_id;
class_id++;
num_of_classes_ = class_id;
} else {
class_label = label->second;
}
std::filesystem::directory_iterator ndir(dpath + "/" + path);
for (const auto np : ndir) {
if (np.path().extension().string() == ".bin") {
std::string entry =
dpath + "/" + np.path().parent_path().stem().string() + "/" + np.path().filename().string();
FileTuple ft = make_tuple(class_label, entry);
vec.push_back(ft);
}
}
}
}
return vec;
}

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MODEL_ZOO_OFFICIAL_TOD_TRAIN_LENET_SRC_DATASET_H_
#define MODEL_ZOO_OFFICIAL_TOD_TRAIN_LENET_SRC_DATASET_H_
#ifndef MINDSPORE_LITE_EXAMPLES_TRAIN_LENET_SRC_DATASET_H_
#define MINDSPORE_LITE_EXAMPLES_TRAIN_LENET_SRC_DATASET_H_
#include <tuple>
#include <string>
@ -42,8 +42,6 @@ class DataSet {
unsigned int expected_data_size() { return expected_data_size_; }
private:
std::vector<FileTuple> ReadFileList(std::string dpath);
std::vector<FileTuple> ReadDir(const std::string dpath);
int ReadMNISTFile(const std::string &ifile, const std::string &lfile, std::vector<DataLabelTuple> *dataset);
void InitializeMNISTDatabase(std::string dpath);
@ -53,4 +51,4 @@ class DataSet {
unsigned int expected_data_size_ = 0;
};
#endif // MODEL_ZOO_OFFICIAL_TOD_TRAIN_LENET_SRC_DATASET_H_
#endif // MINDSPORE_LITE_EXAMPLES_TRAIN_LENET_SRC_DATASET_H_

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MODEL_ZOO_OFFICIAL_TOD_TRAIN_LENET_SRC_NET_RUNNER_H_
#define MODEL_ZOO_OFFICIAL_TOD_TRAIN_LENET_SRC_NET_RUNNER_H_
#ifndef MINDSPORE_LITE_EXAMPLES_TRAIN_LENET_SRC_NET_RUNNER_H_
#define MINDSPORE_LITE_EXAMPLES_TRAIN_LENET_SRC_NET_RUNNER_H_
#include <tuple>
#include <filesystem>
@ -58,4 +58,4 @@ class NetRunner {
static unsigned int seed_;
};
#endif // MODEL_ZOO_OFFICIAL_TOD_TRAIN_LENET_SRC_NET_RUNNER_H_
#endif // MINDSPORE_LITE_EXAMPLES_TRAIN_LENET_SRC_NET_RUNNER_H_

@ -0,0 +1,41 @@
BASE_DIR=$(realpath ../../../../)
APP:=bin/net_runner
MSLIB:=mindspore-lite
MSDIR:=$(realpath package-$(TARGET)/lib)
SRC:=src/net_runner.cc src/dataset.cc
OBJ:=$(SRC:.cc=.o)
CFLAGS := -Ofast -std=c++17 \
-I . \
-I ./msl \
-I ./msl/third_party/flatbuffers/include
ifeq ($(TARGET),arm64)
CXX := ${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++
CFLAGS += --target=aarch64-none-linux-android21 --gcc-toolchain=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fdata-sections -ffunction-sections
LDFLAGS := --target=aarch64-none-linux-android21 --gcc-toolchain=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Wl,--gc-sections
LDFLAGS += -L$(MSDIR) -l$(MSLIB) -pthread -llog -latomic -lm
else
CFLAGS += -g
LDFLAGS := -L$(MSDIR) -l$(MSLIB) -lpthread -Wl,-rpath,$(MSDIR)
endif
LD := ${CXX}
all:$(APP)
$(APP): $(OBJ) $(MSDIR)/lib$(MSLIB).so
@mkdir -p bin
$(LD) $(OBJ) $(LDFLAGS) -o $@
clean:
rm -rf src/*.o bin/
mrproper:
rm -rf dataset package* msl src/*.o bin/ model/*.mindir model/*.ms
%.o:%.cc
$(CXX) $(CFLAGS) -c $< -o $@

@ -0,0 +1,150 @@
# Content
<!-- TOC -->
- [Overview](#overview)
- [Model Architecture](#model-architecture)
- [Dataset](#dataset)
- [Environment Requirements](#environment-requirements)
- [Quick Start](#quick-start)
- [Script Detailed Description](#script-detailed-description)
<!-- /TOC -->
# Overview
This folder holds an example code for on-Device Transfer learning. Part of the code runs on a server using MindSpore infrastructure, another part uses MindSpore Lite conversion utility, and the last part is the actual training of the model on some android-based device.
# Transfer Learning Scheme
In this example of transfer learning we are using a fixed backbone that holds a pretrained [efficientNet](https://arxiv.org/abs/1905.11946) and an adjustable head which is a simple Dense layer. During the training only the head will be updating it's weights. Such training scheme is very efficient in computation power and therefore very relevant for Training-on-Device scenarios.
# Dataset
In this example we use a subset of the [Places dataset](http://places2.csail.mit.edu/) of scenes.
The whole dataset is composed of high resolution as well as small images and sums up to more than 100Gb.
For this demo we will use only the [validation data of small images](http://places2.csail.mit.edu/download.html) which is approximately 500Mb.
- Dataset size501M36,500 224*224 images in 365 classes
- Dataiset formatjpg files
- NoteIn the current release, data is customely loaded using a proprietary DataSet class (provided in dataset.cc). In the upcoming releases loading will be done using MindSpore MindData infrastructure. In order to fit the data to the model it will be preprocessed using [ImageMagick convert tool](https://imagemagick.org/), namely croping and converting to bmp format.
- Note: Only 10 classes out of the 365 will be used in this demo
- Note: 60% of the data will be used for training and 20% will be used for testing and the remaining 20% for validation
- The original dataset directory structure is as follows:
```text
places
├── val_256
│   ├── Places365_val_00000001.jpg
│   ├── Places365_val_00000002.jpg
│   ├── ...
│   ├── Places365_val_00036499.jpg
│   └── Places365_val_00036500.jpg
```
# Environment Requirements
- Server side
- [MindSpore Framework](https://www.mindspore.cn/install/en) - it is recommended to install a docker image
- [MindSpore ToD Framework](https://www.mindspore.cn/tutorial/tod/en/use/prparation.html)
- [Android NDK r20b](https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip)
- [Android SDK](https://developer.android.com/studio?hl=zh-cn#cmdline-tools)
- [ImageMagick convert tool](https://imagemagick.org/)
- A connected Android device
# Quick Start
After installing all the above mentioned, the script in the home directory could be run with the following arguments:
```bash
sh ./prepare_and_run.sh -D DATASET_PATH [-d MINDSPORE_DOCKER] [-r RELEASE.tar.gz] [-t arm64|x86]
```
where:
- DATASET_PATH is the path to the [dataset](#dataset),
- MINDSPORE_DOCKER is the image name of the docker that runs [MindSpore](#environment-requirements). If not provided MindSpore will be run locally
- REALEASE.tar.gz is a pointer to the MindSpore ToD release tar ball. If not provided, the script will attempt to find MindSpore ToD compilation output
- target is defaulted to arm64, i.e., on-device. If x86 is provided, the demo will be run locally. Note that infrastructure is not optimized for device
# Script Detailed Description
The provided `prepare_and_run.sh` script is performing the followings:
- Prepare the trainable transsfer learning model in a `.ms` format
- Prepare the folder that should be pushed into the device
- Copy this folder into the device and run the scripts on the device
See how to run the script and paramaters definitions in the [Quick Start Section](#quick-start)
## Preparing the model
Within the model folder a `prepare_model.sh` script uses MindSpore infrastructure to export the model into a `.mindir` file. The user can specify a docker image on which MindSpore is installed. Otherwise, the pyhton script will be run locally.
The script then converts the `.mindir` to a `.ms` format using the MindSpore ToD converter.
The script accepts a tar ball where the converter resides. Otherwise, the script will attempt to find the converter in the MindSpore ToD build output directory.
## Preparing the Folder
The `transfer_learning_tod.ms` model file is then copied into the `package` folder as well as scripts, the MindSpore ToD library and a subset of the Places dataset. This dataset undergoes preprocessing on the server prior to the packaging.
Finally, the code (in src) is compiled for the target and the binary is copied into the `package` folder.
### Running the code on the device
To run the code on the device the script first uses `adb` tool to push the `package` folder into the device.
It first runs evaluation on the untrained model (to check the accuracy of the untrained model)
It then runs training (which takes some time) and finally it runs evaluation of the trained model using the test data.
# Folder Directory tree
```text
transfer_learning/
├── Makefile # Makefile of src code
├── model
│   ├── effnet.py # Python implementation of efficientNet
│   ├── transfer_learning_export.py # Python script that exports the LeNet model to .mindir
│   ├── prepare_model.sh # script that export model (using docker) then converts it
│   └── train_utils.py # utility function used during the export
├── prepare_and_run.sh # main script that creates model, compiles it and send to device for running
├── prepare_dataset.sh # prepares the Places dataset (crop/convert/organizing folders)
├── README.md # this manual
├── scripts
│   ├── eval.sh # script that load the train model and evaluates its accuracy
│   ├── eval_untrained.sh # script that load the untrained model and evaluates its accuracy
│   ├── places365_val.txt # association of images to classes withiin the Places 365 dataset
│   └── train.sh # script that load the initial model and trains it
├── src
│   ├── dataset.cc # dataset handler
│   ├── dataset.h # dataset class header
│   ├── net_runner.cc # program that runs training/evaluation of models
│   └── net_runner.h # net_runner header
```
When the `prepare_and_run.sh` script is run, the following folder is prepared. It is pushed to the device and then training runs
```text
package-arm64/
├── bin
│   └── net_runner # the executable that performs the training/evaluation
├── dataset
│   ├── 0 # folder containing images 0-99 belonging to 0'th class
│   │   ├── 0.bmp
│   │   ├── 1.bmp
│   │   ├── ....
│   │   ├── 98.bmp
│   │   └── 99.bmp
│   ├── ... # folders containing images 0-99 belonging to 1'st-8'th classes
│   ├── 9 # folder containing images 0-99 belonging to 9'th class
│   │   ├── 0.bmp
│   │   ├── 1.bmp
│   │   ├── ....
│   │   ├── 98.bmp
│   │   └── 99.bmp
├── lib
│   └── libmindspore-lite.so # MindSpore Lite library
├── model
│   └── transfer_learning_tod.ms # model to train
├── eval.sh # script that load the train model and evaluates its accuracy
├── eval_untrained.sh # script that load the untrain model and evaluates its accuracy
└── train.sh # script that load the initial model and train it
```

File diff suppressed because it is too large Load Diff

@ -0,0 +1,34 @@
#!/bin/bash
if [ ! -f "efficient_net_b0.ckpt" ]; then
echo "Pretrained model weights are missing, downloading efficient_net_b0.ckpt"
wget https://download.mindspore.cn/model_zoo/official/lite/efficient_net/efficient_net_b0.ckpt
fi
echo "============Exporting=========="
if [ -n "$1" ]; then
DOCKER_IMG=$1
docker run -w $PWD --runtime=nvidia -v /home/$USER:/home/$USER --privileged=true ${DOCKER_IMG} /bin/bash -c "python transfer_learning_export.py; chmod 444 transfer_learning_tod.mindir; rm -rf __pycache__"
else
echo "MindSpore docker was not provided, attempting to run locally"
python transfer_learning_export.py
fi
CONVERTER="../../../build/tools/converter/converter_lite"
if [ ! -f "$CONVERTER" ]; then
if ! command -v converter_lite &> /dev/null
then
tar -xzf ../../../../../output/mindspore-lite-*-converter-ubuntu-train.tar.gz --strip-components 2 --wildcards --no-anchored converter_lite libmindspore_gvar.so
if [ -f ./converter_lite ]; then
CONVERTER=./converter_lite
else
echo "converter_lite could not be found in MindSpore build directory nor in system path"
exit 1
fi
else
CONVERTER=converter_lite
fi
fi
echo "============Converting========="
LD_LIBRARY_PATH=./ $CONVERTER --fmk=MINDIR --trainModel=true --modelFile=transfer_learning_tod.mindir --outputFile=transfer_learning_tod

@ -0,0 +1,34 @@
# Copyright 2020 Huawei Technologies Co., Ltd
#
# 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
#
# http://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.
# ============================================================================
"""train_utils."""
import mindspore.nn as nn
from mindspore.common.parameter import ParameterTuple
def TrainWrap(net, loss_fn=None, optimizer=None, weights=None):
"""
TrainWrap
"""
if loss_fn is None:
loss_fn = nn.SoftmaxCrossEntropyWithLogits(reduction='mean')
loss_net = nn.WithLossCell(net, loss_fn)
loss_net.set_train()
if weights is None:
weights = ParameterTuple(net.trainable_params())
if optimizer is None:
optimizer = nn.Adam(weights, learning_rate=1e-3, beta1=0.9, beta2=0.999, eps=1e-8,
use_locking=False, use_nesterov=False, weight_decay=0.0, loss_scale=1.0)
train_net = nn.TrainOneStepCell(loss_net, optimizer)
return train_net

@ -0,0 +1,63 @@
# Copyright 2020 Huawei Technologies Co., Ltd
#
# 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
#
# http://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.
# ============================================================================
"""transfer_learning_export."""
import mindspore as M
from mindspore.nn import Cell
from mindspore.train.serialization import load_checkpoint
from mindspore.common.parameter import ParameterTuple
from mindspore.train.serialization import export
from effnet import effnet
import numpy as np
from train_utils import TrainWrap
class TransferNet(Cell):
def __init__(self, backbone, head):
super().__init__(TransferNet)
self.backbone = backbone
self.head = head
def construct(self, x):
x = self.backbone(x)
x = self.head(x)
return x
BACKBONE = effnet(num_classes=1000)
load_checkpoint("efficient_net_b0.ckpt", BACKBONE)
HEAD = M.nn.Dense(1000, 10)
HEAD.weight.set_data(M.Tensor(np.random.normal(
0, 0.1, HEAD.weight.data.shape).astype("float32")))
HEAD.bias.set_data(M.Tensor(np.zeros(HEAD.bias.data.shape, dtype="float32")))
n = TransferNet(BACKBONE, HEAD)
trainable_weights_list = []
trainable_weights_list.extend(n.head.trainable_params())
trainable_weights = ParameterTuple(trainable_weights_list)
M.context.set_context(mode=M.context.PYNATIVE_MODE,
device_target="GPU", save_graphs=False)
BATCH_SIZE = 32
X = M.Tensor(np.ones((BATCH_SIZE, 3, 224, 224)), M.float32)
label = M.Tensor(np.zeros([BATCH_SIZE, 10]).astype(np.float32))
sgd = M.nn.SGD(trainable_weights, learning_rate=0.01, momentum=0.9,
dampening=0.01, weight_decay=0.0, nesterov=False, loss_scale=1.0)
net = TrainWrap(n, optimizer=sgd, weights=trainable_weights)
export(net, X, label, file_name="transfer_learning_tod.mindir", file_format='MINDIR')
print("Exported")

@ -0,0 +1,122 @@
#!/bin/bash
display_usage()
{
echo -e "\nUsage: prepare_and_run.sh -D dataset_path [-d mindspore_docker] [-r release.tar.gz] [-t arm64|x86]\n"
}
checkopts()
{
TARGET="arm64"
DOCKER=""
PLACES_DATA_PATH=""
while getopts 'D:d:r:t:' opt
do
OPTARG=$(echo ${OPTARG} | tr '[A-Z]' '[a-z]')
case "${opt}" in
D)
PLACES_DATA_PATH=$OPTARG
;;
d)
DOCKER=$OPTARG
;;
t)
if [ "$OPTARG" == "arm64" ] || [ "$OPTARG" == "x86" ]; then
TARGET=$OPTARG
else
echo "No such target " $OPTARG
display_usage
exit 1
fi
;;
r)
TARBALL=$OPTARG
;;
*)
echo "Unknown option ${opt}!"
display_usage
exit 1
esac
done
}
checkopts "$@"
if [ "$PLACES_DATA_PATH" == "" ]; then
echo "Places Dataset directory path was not provided"
display_usage
exit 1
fi
if [ "$TARBALL" == "" ]; then
file=$(ls ../../../../output/mindspore-lite-*-runtime-${TARGET}-cpu-train.tar.gz)
if [ -f ${file} ]; then
TARBALL=${file}
else
echo "release.tar.gz was not found"
display_usage
exit 1
fi
fi
# Prepare the model
cd model/ || exit 1
rm -f *.ms
./prepare_model.sh $DOCKER || exit 1
cd ../
# Copy the .ms model to the package folder
PACKAGE=package-${TARGET}
rm -rf ${PACKAGE}
mkdir -p ${PACKAGE}/model
cp model/*.ms ${PACKAGE}/model
# Copy the running script to the package
cp scripts/*.sh ${PACKAGE}/
# Copy the shared MindSpore ToD library
tar -xzf ${TARBALL} --wildcards --no-anchored libmindspore-lite.so
tar -xzf ${TARBALL} --wildcards --no-anchored include
mv mindspore-*/lib ${PACKAGE}/
rm -rf msl
mkdir msl
mv mindspore-*/* msl/
rm -rf mindspore-*
# Convert the dataset into the package
./prepare_dataset.sh ${PLACES_DATA_PATH}
cp -r dataset ${PACKAGE}
echo "==========Compiling============"
make TARGET=${TARGET}
# Copy the executable to the package
mv bin ${PACKAGE}/ || exit 1
if [ "${TARGET}" == "arm64" ]; then
echo "=======Pushing to device======="
adb push ${PACKAGE} /data/local/tmp/
echo "==Evaluating Untrained Model==="
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh eval_untrained.sh"
echo "========Training on Device====="
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh train.sh"
echo
echo "===Evaluating trained Model====="
adb shell "cd /data/local/tmp/package-arm64 && /system/bin/sh eval.sh"
echo
else
cd ${PACKAGE} || exit 1
echo "==Evaluating Untrained Model==="
./eval_untrained.sh
echo "======Training Locally========="
./train.sh
echo "===Evaluating trained Model====="
./eval.sh
cd ..
fi

@ -0,0 +1,19 @@
#!/bin/bash
echo "=======Preparing Dataset======="
[ -d "dataset" ] && echo "dataset was already created" && exit
echo "Preparing dataset"
PLACES_DATA_PATH=$1
class_id=0
classes=("4" "98" "6" "7" "10" "15" "17" "70" "26" "30")
for class in "${classes[@]}"; do
mkdir -p dataset/$class_id
i=0
cat scripts/places365_val.txt | grep -w ${class} | awk '{print $1}' | while read line
do
echo converting ${PLACES_DATA_PATH}/val_256/$line to bmp
convert -colorspace RGB -gravity center -crop '224x224+0+0' ${PLACES_DATA_PATH}/val_256/$line dataset/$class_id/$i.bmp;
i=$(($i+1));
done
class_id=$(($class_id+1))
done

@ -0,0 +1,17 @@
#!/bin/bash
# Copyright 2020 Huawei Technologies Co., Ltd
#
# 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
#
# http://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.
# ============================================================================
LD_LIBRARY_PATH=./lib/ bin/net_runner -f model/transfer_learning_tod_trained.ms -e 0 -d dataset

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save