forked from bitcraze/aideck-gap8-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
ubuntu
committed
Nov 11, 2021
1 parent
27f5f06
commit d106d7c
Showing
28 changed files
with
1,406 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# Copyright (C) 2017 GreenWaves Technologies | ||
# All rights reserved. | ||
|
||
# This software may be modified and distributed under the terms | ||
# of the BSD license. See the LICENSE file for details. | ||
|
||
ifndef GAP_SDK_HOME | ||
$(error Source sourceme in gap_sdk first) | ||
endif | ||
|
||
include common.mk | ||
|
||
LOAD_QUANTIZATION= #-q #to load a tflite quantized model | ||
IMAGE=$(CURDIR)/samples/12_11.pgm | ||
|
||
io=host | ||
|
||
|
||
RAM_FLASH_TYPE ?= HYPER | ||
#PMSIS_OS=freertos | ||
|
||
ifeq '$(RAM_FLASH_TYPE)' 'HYPER' | ||
APP_CFLAGS += -DUSE_HYPER | ||
MODEL_L3_EXEC=hram | ||
MODEL_L3_CONST=hflash | ||
else | ||
APP_CFLAGS += -DUSE_SPI | ||
CONFIG_SPIRAM = 1 | ||
MODEL_L3_EXEC=qspiram | ||
MODEL_L3_CONST=qpsiflash | ||
endif | ||
|
||
|
||
QUANT_BITS?=8 | ||
BUILD_DIR=BUILD | ||
ifeq ($(QUANT_BITS), 8) | ||
MODEL_SQ8=1 | ||
ifeq '$(RAM_FLASH_TYPE)' 'HYPER' | ||
NNTOOL_SCRIPT=model/nntool_script | ||
else | ||
NNTOOL_SCRIPT=model/nntool_script_spi | ||
endif | ||
MODEL_SUFFIX = _SQ8BIT | ||
else | ||
ifeq ($(QUANT_BITS),16) | ||
NNTOOL_SCRIPT=model/nntool_script16 | ||
MODEL_SUFFIX = _16BIT | ||
else | ||
$(error Don\'t know how to build with this bit width) | ||
endif | ||
endif | ||
|
||
$(info Building GAP8 mode with $(QUANT_BITS) bit quantization) | ||
|
||
TRAINED_TFLITE_MODEL=model/$(MODEL_PREFIX).tflite | ||
|
||
include model_decl.mk | ||
|
||
# Here we set the memory allocation for the generated kernels | ||
# REMEMBER THAT THE L1 MEMORY ALLOCATION MUST INCLUDE SPACE | ||
# FOR ALLOCATED STACKS! | ||
CLUSTER_STACK_SIZE=4028 | ||
CLUSTER_SLAVE_STACK_SIZE=1024 | ||
TOTAL_STACK_SIZE=$(shell expr $(CLUSTER_STACK_SIZE) \+ $(CLUSTER_SLAVE_STACK_SIZE) \* 7) | ||
MODEL_L1_MEMORY=$(shell expr 60000 \- $(TOTAL_STACK_SIZE)) | ||
MODEL_L2_MEMORY=250000 | ||
MODEL_L3_MEMORY=8388608 | ||
|
||
pulpChip = GAP | ||
PULP_APP = model | ||
|
||
APP = model | ||
APP_SRCS += $(MODEL_PREFIX).c $(MODEL_GEN_C) $(MODEL_COMMON_SRCS) $(CNN_LIB) | ||
|
||
APP_CFLAGS += -g -O1 -mno-memcpy -fno-tree-loop-distribute-patterns | ||
APP_CFLAGS += -I. -I$(MODEL_COMMON_INC) -I$(TILER_EMU_INC) -I$(TILER_INC) $(CNN_LIB_INCLUDE) -I$(MODEL_BUILD) | ||
APP_CFLAGS += -DPERF -DAT_MODEL_PREFIX=$(MODEL_PREFIX) $(MODEL_SIZE_CFLAGS) | ||
APP_CFLAGS += -DSTACK_SIZE=$(CLUSTER_STACK_SIZE) -DSLAVE_STACK_SIZE=$(CLUSTER_SLAVE_STACK_SIZE) | ||
APP_CFLAGS += -DAT_IMAGE=$(IMAGE) | ||
|
||
READFS_FILES=$(abspath $(MODEL_TENSORS)) | ||
|
||
# all depends on the model | ||
all:: model | ||
|
||
clean:: clean_model | ||
|
||
include train_model.mk | ||
include model_rules.mk | ||
$(info APP_SRCS... $(APP_SRCS)) | ||
$(info APP_CFLAGS... $(APP_CFLAGS)) | ||
include $(RULES_DIR)/pmsis_rules.mk | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Sample MNIST Build using GAPFlow | ||
|
||
This project includes a sample based on a simple model graph defined in Keras. | ||
|
||
It goes from training right through to working code on GAP8 or the same code running on the PC for | ||
debugging purposes. | ||
|
||
* It first trains the network using keras | ||
* It then exports the network to H5 format | ||
* It then converts the H5 file to a TFLITE file using TensorFlow's TFLITE converter | ||
* It then generates an nntool state file by running an nntool script with commands to adjust the tensor and activation order, fuse certain operations together and automatically quantify the graph | ||
* It then uses this state file to generate an AutoTiler graph model | ||
* It then compiles and runs the model to produce GAP8 code | ||
* Finally it builds and runs the produced code on GAP8 | ||
|
||
While this example uses Makefiles the same steps could be achieved with any build system. | ||
|
||
The process can be run to quantize the model in 16 or 8 bits weights and activations. | ||
|
||
## Build and run without Docker | ||
*This example uses the SDK Version `3.7`.* | ||
|
||
To build and run on GAP8: | ||
``` | ||
make all run | ||
``` | ||
To build and run on GVSOC | ||
``` | ||
make all run platform=gvsoc | ||
``` | ||
The input image is specified in the Makefile and loaded with the functions defined in ${GAP_SDK_HOME}/libs/gap_lib/img_io/ImgIO.c | ||
|
||
To clean the generated model and code but not the trained network type | ||
``` | ||
make clean | ||
``` | ||
To clean the trained keras save file type | ||
``` | ||
make clean_train | ||
``` | ||
To build and run the network compiled on the pc | ||
``` | ||
make -f emul.mk all | ||
``` | ||
This will produce an executable, model_emul, that can be used to evaluate files | ||
``` | ||
e.g. ./model_emul images/5558_6.pgm | ||
``` | ||
This mode allows the application to be run with PC tools like valgrind which is very interesting for debugging. | ||
The cluster only has one core in this mode. | ||
|
||
The build defaults to 8 bit quantization. 16 bit quantization can be selected by preceeding the build lines above with QUANT_BITS=16. | ||
``` | ||
e.g. QUANT_BITS=16 make -f emul.mk all | ||
``` | ||
|
||
## Build and run within the docker | ||
*This example uses the SDK Version `3.7`.* | ||
|
||
Navigate to top-level folder of the example | ||
``` | ||
cd <path/to/ai-deck/repository>/GAP8/ai_examples/gapflow_model_extern/ | ||
``` | ||
Build and execute in Docker similar as the other examples | ||
``` | ||
docker run --rm -it -v $PWD:/module/data/ --device /dev/ttyUSB0 --privileged -P gapsdk:3.7 /bin/bash -c 'export GAPY_OPENOCD_CABLE=interface/ftdi/olimex-arm-usb-tiny-h.cfg; source /gap_sdk/configs/ai_deck.sh; cd /module/data/; make clean clean_train clean_model clean_images all run' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#ifndef __BRIDGE_STUBS_H__ | ||
#define __BRIDGE_STUBS_H__ | ||
|
||
#if defined(__PULP_OS__) | ||
|
||
#define BRIDGE_Init() {} | ||
#define BRIDGE_Connect(__wait_bridge, __event) rt_bridge_connect(__wait_bridge, __event) | ||
#define BRIDGE_Open(__name, __flags, __mode, __event) rt_bridge_open(__name, __flags, __mode, __event) | ||
#define BRIDGE_Read(__file, __buffer, __size, __event) rt_bridge_read(__file, __buffer, __size, __event) | ||
#define BRIDGE_Write(__file, __buffer, __size, __event) rt_bridge_write(__file, __buffer, __size, __event) | ||
#define BRIDGE_Close(__file, __event) rt_bridge_close(__file, __event) | ||
#define BRIDGE_Disconnect(__event) rt_bridge_disconnect(__event) | ||
|
||
#endif /* __PULP_OS__ */ | ||
|
||
#endif /* __BRIDGE_STUBS_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Copyright (C) 2020 GreenWaves Technologies | ||
# All rights reserved. | ||
|
||
# This software may be modified and distributed under the terms | ||
# of the BSD license. See the LICENSE file for details. | ||
|
||
MODEL_PREFIX=model | ||
AT_INPUT_WIDTH=28 | ||
AT_INPUT_HEIGHT=28 | ||
AT_INPUT_COLORS=3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Copyright (C) 2017 GreenWaves Technologies | ||
# All rights reserved. | ||
|
||
# This software may be modified and distributed under the terms | ||
# of the BSD license. See the LICENSE file for details. | ||
|
||
$(IMAGES): | ||
(mkdir -p $(IMAGES); $(MODEL_PYTHON) model/save_samples.py -d $@ -n 5) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import os | ||
import numpy as np | ||
from PIL import Image | ||
import random | ||
|
||
|
||
def savelist(data_dir): | ||
""" | ||
从输入根目录获取图像路径、标签列表 | ||
""" | ||
image_paths = [] | ||
image_labels = [] | ||
|
||
print(data_dir) | ||
|
||
image_classes = os.listdir(data_dir) | ||
print(image_classes) | ||
|
||
for image_class in image_classes: | ||
sub_dir = os.path.join(data_dir + "\\" + image_class) | ||
# 进入子类目录 | ||
image_names = os.listdir(sub_dir) | ||
for image_name in image_names: | ||
sub_path = os.path.join(sub_dir + "\\" + image_name) | ||
# 操作每类图片 | ||
image_paths.append(sub_path) | ||
image_labels.append(image_classes.index(sub_dir[38:])) | ||
|
||
|
||
# 随机打乱 | ||
random.seed(123) | ||
random.shuffle(image_paths) | ||
random.seed(123) | ||
random.shuffle(image_labels) | ||
|
||
image_count = len(image_paths) | ||
split = 0.2 | ||
|
||
val_image_paths = image_paths[:int(split*image_count)] | ||
train_image_paths = image_paths[int(split*image_count):] | ||
|
||
val_image_labels = image_labels[:int(split*image_count)] | ||
train_image_labels = image_labels[int(split*image_count):] | ||
|
||
return train_image_paths, train_image_labels, val_image_paths, val_image_labels | ||
|
||
|
||
|
||
|
||
def save_as_numpy(image_paths, image_labels,str): | ||
d = len(image_paths) | ||
print(d) | ||
data = np.empty((d, 28, 28, 3),dtype=np.uint8) | ||
print(data) | ||
while d>0: | ||
img = Image.open(image_paths[d-1]) | ||
img = img.resize((28,28),Image.ANTIALIAS) | ||
img_ndarray = np.array(img) | ||
print(img_ndarray.shape) | ||
data[d - 1] = img_ndarray | ||
d = d - 1 | ||
|
||
print(str + "转换完成") | ||
print(data) | ||
|
||
d = len(image_labels) | ||
label = np.zeros((d),dtype=np.uint8) | ||
print(label) | ||
while d>0: | ||
label[d - 1] = image_labels[d-1] | ||
d = d - 1 | ||
print(str + "转换完成") | ||
print(label) | ||
|
||
np.save(str + '_images.npy',data) | ||
np.save(str + '_labels.npy',label) | ||
np.savez(str + '.npz',image=data,label=label) | ||
|
||
|
||
|
||
|
||
if __name__=='__main__': | ||
|
||
data_dir = "" | ||
|
||
train_images, train_labels, val_images, val_labels = savelist(data_dir) | ||
|
||
|
||
save_as_numpy(train_images, train_labels, str='train') | ||
save_as_numpy(val_images, val_labels, str='val') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Copyright (C) 2020 GreenWaves Technologies | ||
# All rights reserved. | ||
|
||
# This software may be modified and distributed under the terms | ||
# of the BSD license. See the LICENSE file for details. | ||
|
||
include common.mk | ||
|
||
QUANT_BITS?=8 | ||
BUILD_DIR=BUILD | ||
ifeq ($(QUANT_BITS), 8) | ||
MODEL_SQ8=1 | ||
NNTOOL_SCRIPT=model/nntool_script_emul | ||
MODEL_SUFFIX = _SQ8BIT_EMUL | ||
else | ||
ifeq ($(QUANT_BITS),16) | ||
NNTOOL_SCRIPT=model/nntool_script_emul16 | ||
MODEL_SUFFIX = _16BIT_EMUL | ||
else | ||
$(error Don\'t know how to build with this bit width) | ||
endif | ||
endif | ||
TRAINED_TFLITE_MODEL=model/$(MODEL_PREFIX).tflite | ||
|
||
include model_decl.mk | ||
|
||
MODEL_GEN_EXTRA_FLAGS= -f $(MODEL_BUILD) | ||
MODEL_GENFLAGS_EXTRA+= | ||
CC = gcc | ||
CFLAGS += -g -m32 -O0 -D__EMUL__ -DAT_MODEL_PREFIX=$(MODEL_PREFIX) $(MODEL_SIZE_CFLAGS) -DPERF | ||
INCLUDES = -I. -I$(TILER_EMU_INC) -I$(TILER_INC) $(CNN_LIB_INCLUDE) -I$(MODEL_BUILD) -I$(MODEL_COMMON_INC) | ||
LFLAGS = | ||
LIBS = | ||
SRCS = $(MODEL_PREFIX)_emul.c $(MODEL_GEN_C) $(MODEL_COMMON_SRCS) $(CNN_LIB) | ||
$(info CNN_LIB++ $(CNN_LIB)) | ||
$(info SRCS++ $(SRCS)) | ||
BUILD_DIR = BUILD_EMUL | ||
|
||
OBJS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(SRCS)) | ||
|
||
MAIN = $(MODEL_PREFIX)_emul | ||
# Here we set the memory allocation for the generated kernels | ||
# REMEMBER THAT THE L1 MEMORY ALLOCATION MUST INCLUDE SPACE | ||
# FOR ALLOCATED STACKS! | ||
CLUSTER_STACK_SIZE=2048 | ||
CLUSTER_SLAVE_STACK_SIZE=1024 | ||
TOTAL_STACK_SIZE=$(shell expr $(CLUSTER_STACK_SIZE) \+ $(CLUSTER_SLAVE_STACK_SIZE) \* 7) | ||
MODEL_L1_MEMORY=$(shell expr 60000 \- $(TOTAL_STACK_SIZE)) | ||
MODEL_L2_MEMORY=200000 | ||
MODEL_L3_MEMORY=8388608 | ||
|
||
# hram - HyperBus RAM | ||
# qspiram - Quad SPI RAM | ||
MODEL_L3_EXEC=hram | ||
# hflash - HyperBus Flash | ||
# qpsiflash - Quad SPI Flash | ||
MODEL_L3_CONST=hflash | ||
|
||
all: model $(MAIN) | ||
|
||
$(OBJS) : $(BUILD_DIR)/%.o : %.c | ||
@mkdir -p $(dir $@) | ||
$(CC) $(CFLAGS) -c $< $(INCLUDES) -MD -MF $(basename $@).d -o $@ | ||
|
||
$(MAIN): $(OBJS) | ||
$(CC) $(CFLAGS) -MMD -MP $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS) | ||
|
||
clean: clean_model | ||
$(RM) -r $(BUILD_DIR) | ||
$(RM) $(MAIN) | ||
|
||
.PHONY: depend clean | ||
include train_model.mk | ||
include model_rules.mk |
Oops, something went wrong.