Невозможно скопировать из тензора TensorFlowLite (Identity) с формой [1, 4] в объект Java с формой [1, 10, 4]

#java #android #tensorflow #machine-learning #tensorflow-lite

#java #Android #тензорный поток #машинное обучение #tensorflow-lite

Вопрос:

Обучил TFLite-модель граней и попытался реализовать ее на Android.

 final List<Detector.Recognition> results = detector.recognizeImage(croppedBitmap);
 

в этой строке я получил сообщение об ошибке

 E/AndroidRuntime: FATAL EXCEPTION: inference
    Process: org.tensorflow.lite.examples.detection, PID: 14805
    java.lang.IllegalArgumentException: Cannot copy from a TensorFlowLite tensor (Identity) with shape [1, 4] to a Java object with shape [1, 10, 4].
        at org.tensorflow.lite.Tensor.throwIfDstShapeIsIncompatible(Tensor.java:482)
        at org.tensorflow.lite.Tensor.copyTo(Tensor.java:252)
        at org.tensorflow.lite.NativeInterpreterWrapper.run(NativeInterpreterWrapper.java:183)
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:365)
        at org.tensorflow.lite.examples.detection.tflite.TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java:211)
        at org.tensorflow.lite.examples.detection.DetectorActivity$2.run(DetectorActivity.java:184)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.os.HandlerThread.run(HandlerThread.java:65)
 

входные данные детектора

  // Configuration values for the prepackaged SSD model.
  private static final int TF_OD_API_INPUT_SIZE = 448; // before was 300 and gave error
  private static final boolean TF_OD_API_IS_QUANTIZED = true;
  private static final String TF_OD_API_MODEL_FILE = "model.tflite";
  private static final String TF_OD_API_LABELS_FILE = "labels.txt";
  private static final DetectorMode MODE = DetectorMode.TF_OD_API;
  // Minimum detection confidence to track a detection.
  private static final float MINIMUM_CONFIDENCE_TF_OD_API = 0.5f;
  private static final boolean MAINTAIN_ASPECT = false;
  private static final Size DESIRED_PREVIEW_SIZE = new Size(640, 480);
  private static final boolean SAVE_PREVIEW_BITMAP = false;
  private static final float TEXT_SIZE_DIP = 10;

 int cropSize = TF_OD_API_INPUT_SIZE;

try {
  detector =
      TFLiteObjectDetectionAPIModel.create(
          this,
          TF_OD_API_MODEL_FILE,
          TF_OD_API_LABELS_FILE,
          TF_OD_API_INPUT_SIZE,
          TF_OD_API_IS_QUANTIZED);
  cropSize = TF_OD_API_INPUT_SIZE;
} catch (final IOException e) {
  e.printStackTrace();
  LOGGER.e(e, "Exception initializing Detector!");
  Toast toast =
      Toast.makeText(
          getApplicationContext(), "Detector could not be initialized", Toast.LENGTH_SHORT);
  toast.show();
  finish();
}
 

какой параметр я должен изменить, чтобы он работал? это проблема в java или я должен переобучить модель?

Обновление: проблема, похоже, в библиотеке tensorflow из-за несоответствия между картой ввода и вывода. Надеюсь, кто-нибудь знает, как устранить это несоответствие. Ниже приведены переменные отладки. строка ошибки

ввод

карта вывода

Обновление 2: сначала я установил демонстрационное приложение из https://www.tensorflow.org/lite/models/object_detection/overview#get_started . Он может обнаруживать множество объектов (человек, кошка, ноутбук и так далее). Затем я обучил модель https://colab.research.google.com/drive/1Ezjt7iytvbtSDO2kgnzfLSoVT_lcKzBJ?usp=sharing перейдя по этой ссылке https://www.tensorflow.org/lite/tutorials/model_maker_image_classification . Возможно, я обучил его неправильно, потому что в исходных тензорах модели shapecopy имеет форму [1,10,4] и соответствует форме объекта копирования. когда я пытаюсь применить свою модель, shapecopy равен [1,4], и это вызывает исключение

несоответствие формы

Комментарии:

1. Это модель и объект, где нужно указать несоответствие размера ответа. Загляните в org.tensorflow.lite.examples.detection.tflite. TFLiteObjectDetectionAPIModel.recognizeImage(TFLiteObjectDetectionAPIModel.java: 211) в разделе отладка и проверка размеров. Чтобы проверить размер вывода модели tflite, используйте Netron или аналогичный.

2. @AlexK. пожалуйста, смотрите post update, я отладил и увидел содержимое входных и выходных переменных карты. Что я должен изменить, чтобы код работал?

3. Порядок вывода выглядит правильно, оставшийся элемент является моделью. Используете ли вы стандартную модель, подобную этой , или какую-либо пользовательскую подготовку? Похоже, что используемая вами модель имеет 1-й вывод, называемый «Identity» и shape [1] [4], в то время как стандартные модели обнаружения объектов имеют форму вывода [1] [NUM_DET] [4] .

4. Я обучил новую модель, colab colab.research.google.com/drive /…

5. следуйте этому руководству: tensorflow.org/lite/tutorials/model_maker_image_classification

Ответ №1:

Используемая пользовательская модель имеет выходные данные, отличные от используемых в примере для обновления приложения для измененной модели:

  1. исследуйте новую (пользовательскую) модель и определите входные и выходные формы (я предпочитаю использовать для этого приложение Netron — откройте с его помощью свою пользовательскую модель TFLite)
  2. измените буферы входных и выходных данных в приложении, чтобы сопоставить соответствующие входные и выходные данные с вашей моделью: пример, который вы используете, совпадает с вашим вводом, но вывод должен быть изменен на (см. Рядом TFLiteObjectDetectionAPIModel.java@195 )

    resultLabel = new float[1][4];

    Map<Integer, Object> outputMap = new HashMap<>();

    outputMap.put(0, resultLabel);

Комментарии:

1. Привет, это стандартная модель (из демонстрационного приложения) результат imgur.com/gallery/v2XwIgx ] , и это imgur.com/gallery/2P9CPBJ пользовательская модель, подготовленная мной.

2. Здравствуйте, я изменил эту часть кода, ошибка исчезла, но теперь она ничего не обнаруживает..

3. Вы имели в виду, что все время возвращает один и тот же класс?

4. Нет, результаты распознавания всегда пусты imgur.com/gallery/jVGUrvr

5. У вас обученный классификатор, а не детектор. Классификатор отвечает на вопрос «Что на картинке», как в вашем случае — он классифицирует зевоту, отсутствие зевоты, открытые или закрытые глаза. Если вам нужен детектор, у вас должна быть модель, которая выводит прямоугольник обнаружения, класс обнаружения, достоверность. И входные данные должны быть помечены областями определенного класса (например, глаз, рот и т.д.).