Add K210code relevant to the pretrained model

master
bj-wanghz 2019-02-15 18:07:13 +08:00
parent 7710199dd4
commit d80f0d2ac2
6 changed files with 80859 additions and 0 deletions

44
K210code/README.md Normal file
View File

@ -0,0 +1,44 @@
### *pb* file to C file
Download [nncase](https://github.com/kendryte/nncase) tool and uncompress it. You'll get `ncc` directory.
#### *pb* file to tflite
Copy the pretrained model `mobilenetv1_1.0.pb` in `pretrained` directory to `ncc\bin`. Rename it to `mobilenetv1.pb` to avoid the function name error in the following steps.
Enter `ncc\bin` directory from *cmd*.
```shell
.\toco.exe --input_file=mobilenetv1.pb --input_format=TENSORFLOW_GRAPHDEF --output_file=mobilenetv1.tflite --output_format=TFLITE --input_shape=1,224,224,3 --input_array=inputs --output_array=MobileNetV1/Bottleneck2/BatchNorm/Reshape_1 --inference=FLOAT
```
#### tflite to C code
Enter `ncc` directory and place the dataset into `ncc\dataset` directory.
```shell
.\ncc.exe -i tflite -o k210code --dataset .\dataset\ .\bin\mobilenetv1.tflite .\bin\mobilenetv1.c
```
### Prepare image for test
Convert an image, for example `eagle.jpg`, to a C file.
```python
import numpy as np
import matplotlib.pyplot as plt
img = plt.imread('eagle.jpg')
img = np.transpose(img,[2,0,1]) # KPU requires NCHW format,
# while Tensorflow requires NHWC.
with open('image.c','w') as f:
print('const unsigned char gImage_image[]={', file=f)
print(', '.join([str(i) for i in img.flatten()]), file=f)
print('};', file=f)
```
### Test
Copy the `K210code` directory to `kendryte-standalone-sdk\src`. Build and download to KD233 to check the results.
**Note**: `develop` branch of `kendryte-standalone-sdk` is required.

BIN
K210code/eagle.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

3
K210code/image.c Normal file

File diff suppressed because one or more lines are too long

113
K210code/main.c Normal file
View File

@ -0,0 +1,113 @@
/* Copyright 2018 Canaan Inc.
*
* 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.
*/
#include <stdio.h>
#include "kpu.h"
#include <platform.h>
#include <printf.h>
#include <string.h>
#include <stdlib.h>
#include <sysctl.h>
#include "uarths.h"
#include "mobilenetv1.h"
#define PLL0_OUTPUT_FREQ 800000000UL
#define PLL1_OUTPUT_FREQ 300000000UL
volatile uint32_t g_ai_done_flag;
#define IN_SIZE 224
#define OUT_SIZE 7 * 7 * 1024
#define FEATURE_SIZE 1000
volatile uint32_t g_cnt_layer;
uint8_t g_kpu_outbuf[OUT_SIZE] __attribute__((aligned(128)));
float features[FEATURE_SIZE];
extern const unsigned char gImage_image[] __attribute__((aligned(128)));
kpu_task_t task;
static int ai_done(void *ctx)
{
g_ai_done_flag = 1;
return 0;
}
int ai_step(void *ctx)
{
switch (g_cnt_layer)
{
case 0 ... 25:
kpu_conv2d(task.layers + g_cnt_layer);
break;
case 26:
kpu_conv2d_output(task.layers + g_cnt_layer, 5, g_kpu_outbuf, ai_step, NULL);
break;
case 27:
{
quantize_param_t q1 = { .scale = 0.0163548170351515,.bias = 0 }, q2 = { .scale = 0.0021889562700309,.bias = 0 };
kpu_global_average_pool(g_kpu_outbuf, &q1, 7*7, 1024, AI_IO_BASE_ADDR + task.layers[g_cnt_layer].image_addr.data.image_src_addr * 64, &q2);
kpu_matmul_begin(task.layers + g_cnt_layer, 5, (uint64_t *)g_kpu_outbuf, ai_done, NULL);
break;
}
default:
printf("Unexpcted.\n");
while (1);
break;
}
printf("%d\n", g_cnt_layer);
g_cnt_layer++;
return 0;
}
int main()
{
/* Set CPU and dvp clk */
sysctl_pll_set_freq(SYSCTL_PLL0, PLL0_OUTPUT_FREQ);
sysctl_pll_set_freq(SYSCTL_PLL1, PLL1_OUTPUT_FREQ);
sysctl_clock_enable(SYSCTL_CLOCK_AI);
uarths_init();
plic_init();
sysctl_enable_irq();
kpu_task_mobilenetv1_init(&task);
size_t j;
for (j = 0; j < 1; j++)
{
g_cnt_layer = 0;
g_ai_done_flag = 0;
kpu_init(task.eight_bit_mode, ai_step, NULL);
/* start to calculate */
uint64_t t1 = sysctl_get_time_us();
kpu_input_with_padding(task.layers, gImage_image, IN_SIZE, IN_SIZE, 3);
sysctl_disable_irq();
ai_step(NULL);
sysctl_enable_irq();
while (!g_ai_done_flag){}
quantize_param_t q = { .scale = task.output_scale,.bias = task.output_bias };
kpu_matmul_end(g_kpu_outbuf, FEATURE_SIZE, features, &q);
t1 = sysctl_get_time_us() - t1;
printf("takes %f ms\n", t1 / 1000.0);
size_t i;
for (i = 0; i < FEATURE_SIZE; i++)
printf("%f, ", features[i]);
printf("done\n");
}
while (1)
;
}

80697
K210code/mobilenetv1.c Normal file

File diff suppressed because it is too large Load Diff

2
K210code/mobilenetv1.h Normal file
View File

@ -0,0 +1,2 @@
void kpu_task_mobilenetv1_init(kpu_task_t* task);