Dear all,
I tested RKNN with Mobilenet by comparing outputs by RKNN and onnxruntime on TB-96AIoT.
But the test failed and I am thinking the board does not work correctly, but I would appreciate to you if you tell me my fault.
The step is as below:
-
Prepare jpg image (I used one from ImageNet dataset) and onnx model.
-
Run inference with onnxruntime. Argmax of the model output is 65. The code is as below:
#!/usr/bin/env python3
import os
import cv2
import numpy as np
import onnxruntime
def print_model_summary(onnx_sess):
print("[Model Summary]")
print("Inputs:")
for i in onnx_sess.get_inputs():
print(i)
print("Outputs:")
for i in onnx_sess.get_outputs():
print(i)
print("")
def gen_input():
jpg = "ILSVRC2012_val_00000001.JPEG"
img = cv2.imread(jpg)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
x = img
x = x.astype(np.float32)
x = (x/255.0 - (0.485, 0.456, 0.406)) / (0.229, 0.224, 0.225)
x = np.transpose(x, (2, 0, 1))
x = np.expand_dims(x, axis=0)
x = x.astype(np.float32)
return (x, os.path.basename(jpg))
def main():
onnx_file = "mobilenetv2-7.onnx"
sess = onnxruntime.InferenceSession(onnx_file)
print_model_summary(sess)
x, jpg = gen_input()
print("Process {}".format(jpg))
x = x.astype(np.float32)
result = sess.run(["mobilenetv20_output_flatten0_reshape0"],
{"data": x})[0].astype(np.float32)
print("Argmax: {}".format(result.argmax()))
if __name__ == "__main__":
main()
- Convert ONNX model to RKNN model (
mobilenetv2-7.rknn
) with rknn-toolkit and below script:
#!/usr/bin/env python3
import sys
from rknn.api import RKNN
def main(onnx_path):
# Create RKNN object
rknn = RKNN()
ret = rknn.load_onnx(model=onnx_path)
if ret != 0:
raise 'Loading ' + onnx_path + ' failed!'
channel_mean_value="#".join(["0 0 0 1"])
ret = rknn.config(batch_size=1,
channel_mean_value=channel_mean_value,
target_platform=['rk1808'])
if ret != 0:
raise 'Configuring RKNN failed!'
ret = rknn.build(do_quantization=False)
if ret != 0:
raise 'Building RKNN model failed!'
ret = rknn.export_rknn(onnx_path.replace('.onnx', '.rknn'))
if ret != 0:
raise 'Exporting RKNN model failed!'
if __name__ == "__main__":
main(sys.argv[1])
- Apply the below patch to RKNPUTools and build
rknn_mobilenet
.
diff --git a/rknn-api/Linux/rknn_api_sdk/rknn_mobilenet.cpp b/rknn-api/Linux/rknn_api_sdk/rknn_mobilenet.cpp
index 7a2b178..f323ed1 100755
--- a/rknn-api/Linux/rknn_api_sdk/rknn_mobilenet.cpp
+++ b/rknn-api/Linux/rknn_api_sdk/rknn_mobilenet.cpp
@@ -73,10 +73,21 @@ int ReadLabelsFile(const string& file_name,
return 0;
}
+static float input_buf[224*224*3];
+int uint82float_input(const uint8_t *src, float *dst, size_t n_pixels,
+ const std::tuple<float, float, float> &mean,
+ const std::tuple<float, float, float> &std) {
+ for (size_t i = 0; i < n_pixels; i++) {
+ dst[3*i + 0] = ((float)src[3*i + 0]/255.0f - std::get<0>(mean)) / std::get<0>(std);
+ dst[3*i + 1] = ((float)src[3*i + 1]/255.0f - std::get<1>(mean)) / std::get<1>(std);
+ dst[3*i + 2] = ((float)src[3*i + 2]/255.0f - std::get<2>(mean)) / std::get<2>(std);
+ }
+}
+
int main(int argc, char** argv)
{
const char *img_path = "/tmp/dog.jpg";
- const char *model_path = "/tmp/mobilenet_v1-tf.rknn";
+ const char *model_path = "/tmp/mobilenetv2-7.rknn";
const char *lable_path = "/tmp/labels.txt";
const int output_elems = 1001;
@@ -88,9 +99,9 @@ int main(int argc, char** argv)
const int output_index = 0; // node name "MobilenetV1/Predictions/Reshape_1"
// Load image
- cv::Mat img = cv::imread(img_path, 1);
+ cv::Mat img = cv::imread(img_path);
if(!img.data) {
- printf("cv::imread %s fail!\n", img_path);
+ printf("cv::imread %s fail!: %s\n", img_path, strerror(errno));
return -1;
}
if(img.cols != img_width || img.rows != img_height)
@@ -102,7 +113,7 @@ int main(int argc, char** argv)
// Load model
FILE *fp = fopen(model_path, "rb");
if(fp == NULL) {
- printf("fopen %s fail!\n", model_path);
+ printf("fopen %s fail!: %s\n", model_path, strerror(errno));
return -1;
}
fseek(fp, 0, SEEK_END);
@@ -110,7 +121,7 @@ int main(int argc, char** argv)
void *model = malloc(model_len);
fseek(fp, 0, SEEK_SET);
if(model_len != fread(model, 1, model_len, fp)) {
- printf("fread %s fail!\n", model_path);
+ printf("fread %s fail!: %s\n", model_path, strerror(errno));
free(model);
return -1;
}
@@ -136,8 +147,11 @@ int main(int argc, char** argv)
goto Error;
}
+ assert(img_width == 224);
+ assert(img_height == 224);
+ uint82float_input(img.data, input_buf, 224*224, std::make_tuple(0.485f, 0.456f, 0.406f), std::make_tuple(0.229f, 0.224f, 0.225f));
inputs[0].index = input_index;
- inputs[0].buf = img.data;
+ inputs[0].buf = input_buf;
inputs[0].size = img_width * img_height * img_channels;
inputs[0].pass_through = false;
inputs[0].type = RKNN_TENSOR_UINT8;
- Copy the jpg image, rknn model and
rknn_mobilenet
in appropriate directory on TB-96AIoT. and run it.
After the execution I got the below output (The performance related is not pasted here) and found it does not work as expected:
D RKNNAPI: ==============================================
D RKNNAPI: RKNN VERSION:
D RKNNAPI: API: 1.3.0 (c5654ea build: 2019-12-25 14:12:00)
D RKNNAPI: DRV: 1.3.1 (6ebb4d7 build: 2020-01-02 09:37:58)
D RKNNAPI: ==============================================
-nan: 1000 toilet tissue
230.125: 862 toilet seat
220.5: 470 caldron
197.875: 626 lifeboat
185.125: 556 fire engine
Is there something wrong on my steps?
Thank you.
p.s.
Branch ID is here:
RKNPUTools 9ecccf4123054ad23823f1ed7c2ba6e8ea65ed96
rknn-toolkit 6c017fdb6f6264116781058d8bf0a093e796832a