tflite.run () возвращает один и тот же вывод для разных входных значений - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь создать приложение android для распознавания памятников. Входные данные меняются при каждом запуске, но возвращаемый результат всегда один и тот же.

Ниже приведены фрагменты кода

для загрузки модели tflite, хранящейся в каталоге ресурсов

private ByteBuffer loadModelFile(String filename) throws IOException {
        AssetFileDescriptor fileDescriptor = this.getAssets().openFd(filename);
        FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
        FileChannel fileChannel = inputStream.getChannel();
        long startOffset = fileDescriptor.getStartOffset();
        long declaredLength = fileDescriptor.getDeclaredLength();
        return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
    }

для инициализации tflite. интерпретатор

predict.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                try {
                    tflite = new Interpreter(loadModelFile("converted_model.tflite"));
                    Log.println(7,"tflite", "tflite init");
                    doInference(picFile);

                } catch (Exception e) {
                    System.out.println(e);
                }

            }
        });

для запуска модели

@RequiresApi(api = Build.VERSION_CODES.O)
    public void doInference(File photo) throws IOException {
        img = findViewById(R.id.imgToDisp);
        Bitmap bitmapImg = BitmapFactory.decodeFile(pathToFile);
        img.setImageBitmap(bitmapImg);

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmapImg.compress(Bitmap.CompressFormat.JPEG, 50, stream);
        byte[] arr = stream.toByteArray();

        changedim = new float[1][150][150][3];
        outputval = new float[1][28];

        int m = 0;
        for (int i = 0; i < 1; i++) {
            for (int j = 0; j < 150; j++) {
                for (int k = 0; k < 150; k++) {
                    for (int l = 0; l < 3; l++) {
                        byte a = arr[m++];
                        changedim[i][j][k][l] = Byte.toUnsignedLong(a);
                    }
                }
            }
        }

        tflite.run(changedim, outputval);

        for(int i=0;i<28;i++) {
            Log.println(7,"outputval",i+" "+outputval[0][i]);
        }

        path = findViewById(R.id.path);
        String out = "";

        float[] op = outputval[0];
        int ind = 0;

        float max = op[0];

        while (op[ind] != 1) {
            ind++;
            //Log.println(7,"op", " "+op[ind]+" "+ind);
        }

        for (float f : op) {
            out += Float.toString(f) + ",";
        }

        predict.setText("result: " + labels.get(ind));
        Log.println(7, "label", ind + " " + labels.get(ind));
        //path.setText(""+pathToFile);
    }

вход в модель должен быть изображением размером 150 * 150, преобразованным в 4d массив float32 формы 1 * 150 * 150 * 3

1 Ответ

0 голосов
/ 15 марта 2020

Входными данными для модели являются значения цвета отдельных пикселей. Который можно извлечь с помощью

 int p = bitmapImg.getPixel(j, k);
 int R = (p >> 16) & 0xff;
 int G = (p >> 8) & 0xff;
 int B = p & 0xff;

, измените его, и ваша модель будет работать правильно!

...