Toybrick

标题: 模型推理输入不一样,但为什么输出是一样的? [打印本页]

作者: 求大佬指教    时间: 2019-11-26 13:34
标题: 模型推理输入不一样,但为什么输出是一样的?
本帖最后由 求大佬指教 于 2019-11-26 13:38 编辑

在Android studio里debug时出现两次推理结果是一样的
[attach]745[/attach]两个输入分别如下:
[attach]748[/attach][attach]749[/attach]
native是下面这样写的:
  1. JNIEXPORT jfloatArray JNICALL Java_MicroBrainFaceRec_RecFunctions_FaceRecFeature
  2.         (JNIEnv *env,jobject obj, jint handle,jbyteArray bitmap, jint channels){

  3.     uint8_t *rgba = NULL;
  4.     // Get matrix pointer
  5.     if (NULL != bitmap) {
  6.         rgba = (uint8_t *)env->GetByteArrayElements(bitmap, 0);
  7.     } else {
  8.         LOGE("caffe-jni predict(): invalid args: jrgba(NULL)");
  9.         return nullptr;
  10.     }
  11.     int const rgba_len = env->GetArrayLength(bitmap);
  12.     LOGI("rgba_len= %d\n", rgba_len);
  13.     float *inData = (float*)malloc(rgba_len* sizeof(float));
  14.     //float inData[49152]={};
  15.     size_t plane_size = 128*128;
  16.     for (size_t i = 0; i < plane_size; i++) {
  17.         inData[i] = static_cast<float>(rgba[i * 3 + 2]);                   // B
  18.         inData[plane_size + i] = static_cast<float>(rgba[i * 3 + 1]);      // G
  19.         inData[2 * plane_size + i] = static_cast<float>(rgba[i * 3]);      // R
  20.         // Alpha is discarded
  21.         inData[i] = (inData[i] - 127.5) * 0.0078125;
  22.         inData[plane_size + i] = (inData[plane_size + i] - 127.5) * 0.0078125;
  23.         inData[2 * plane_size + i] = (inData[2 * plane_size + i] - 127.5) * 0.0078125;
  24.     }
  25.     //float outFeature[512] = {};
  26.     jfloatArray outFeature = env->NewFloatArray(512);
  27.     jfloat* y0 = env->GetFloatArrayElements(outFeature,0);
  28.     use_rknn::run_rknn(inData,y0);
  29.     env->ReleaseFloatArrayElements(outFeature, y0, 0);
  30.     free(inData);
  31.     return outFeature;
  32. }
复制代码
其中用rknn设置如下:
  1.   bool run_rknn(float *inData, float *y0){
  2.         if(!created) {
  3.             LOGE("run: create hasn't successful!");
  4.             return false;
  5.         }

  6.         rknn_input inputs[1];
  7.         inputs[0].index = input_index;
  8.         inputs[0].buf = inData;
  9.         inputs[0].size = inputs_attr[0].n_elems* sizeof(float);
  10.         //inputs[0].size = Size;
  11.         inputs[0].pass_through = false;
  12.         inputs[0].type = RKNN_TENSOR_FLOAT32;
  13.         inputs[0].fmt = RKNN_TENSOR_NCHW;
  14.         int ret = rknn_inputs_set(ctx, 1, inputs);
  15.         if(ret < 0) {
  16.             LOGE("rknn_input_set fail! ret=%d\n", ret);
  17.             return false;
  18.         }

  19.         ret = rknn_run(ctx, nullptr);
  20.         if(ret < 0) {
  21.             LOGE("rknn_run fail! ret=%d\n", ret);
  22.             return false;
  23.         }


  24.         rknn_output outputs[1];
  25.         outputs[0].want_float = true;
  26.         outputs[0].is_prealloc = true;
  27.         outputs[0].index = output_index0;
  28.         outputs[0].buf = y0;
  29.         outputs[0].size = outputs_attr[0].n_elems * sizeof(float);;

  30.         ret = rknn_outputs_get(ctx, 1, outputs, nullptr);
  31.         if(ret < 0) {
  32.             LOGE("rknn_outputs_get fail! ret=%d\n", ret);
  33.             return false;
  34.         }

  35.         rknn_outputs_release(ctx, 1, outputs);
  36.         return true;
  37.     }
复制代码
运行的时候为什么第二个结果和第一个是一样的,我将两个分别注释以后,运行都可以得到正确的结果,但是同时运行的时候第二个结果总和第一个一样,这是为什么呢?
作者: jefferyzhang    时间: 2019-11-26 14:23
多取几次output看下,在async模式下你下一次的输出是这一次输入推理的结果。
作者: 求大佬指教    时间: 2019-11-26 15:11
本帖最后由 求大佬指教 于 2019-11-26 15:12 编辑
jefferyzhang 发表于 2019-11-26 14:23
多取几次output看下,在async模式下你下一次的输出是这一次输入推理的结果。 ...

[attach]750[/attach]
好像是这么回事,下一次结果是上一次推理的数值,总是慢一拍,这是为什么呢?刚才的解释我不太明白请问我需要怎么改,才能正常输出呢?

作者: jefferyzhang    时间: 2019-11-26 15:15
本帖最后由 jefferyzhang 于 2019-11-26 15:16 编辑

参看文档:《Rockchip_User_Guide_RKNN_API_V1.2.0_CN》
第 : 3.1.1 rknn_init & rknn_init2

RKNN_FLAG_ASYNC_MASK:打开异步模式。
打开之后,rknn_outputs_get 将不会阻塞太久,因为它直接返回的上一帧的推理结果(第一帧的推理结果除外),
这将显著提高 单线程模式下的推理帧率,但代价是 rknn_outputs_get 返回的不是当前帧的推理结果。
但当 rknn_run 和 rknn_outputs_get 不在同一个线程时,则无需打开该异步模式。

作者: 求大佬指教    时间: 2019-11-26 20:56
jefferyzhang 发表于 2019-11-26 15:15
参看文档:《Rockchip_User_Guide_RKNN_API_V1.2.0_CN》
第 : 3.1.1 rknn_init & rknn_init2

好的,非常感谢




欢迎光临 Toybrick (https://t.rock-chips.com/) Powered by Discuz! X3.3