Ошибка преобразования строки при попытке вызвать модель Tensorflow Tflite

Я следую этому руководству, чтобы запустить в моем приложении Xamarin.Android простой детектор tflite: обнаружение мобильных устройств в реальном времени

Я могу подтвердить, что демонстрация приложения из этой статьи работает нормально. Однако, как видите, статья основана на специально обученной модели для каски. Я просто хочу поменять местами свою собственную обученную модель. Поэтому я зашел на сайт Google Cloud Platform > Vision и создал / обучил новую модель. После того, как это было сделано, я экспортировал его как модель tflite. Когда я это сделал, я просто попытался поменять местами свою модель и метки, и теперь я получаю следующее исключение:

Ошибка преобразования строки: недопустимая последовательность байтов во входных данных.

at (оболочка, управляемая-родной) System.Runtime.InteropServices.Marshal.PtrToStringAnsi(intptr) в Emgu.TF.Lite.TfLiteInvoke.TfliteErrorHandler (статус System.Int32, System.IntPtr errMsg) [0x00001] \Ensight\Ensight.LPR.Mobile\TF\CameraTF\Emgu.TF.Lite.Shared\TFLiteInvoke.cs:26 в (внутренняя оболочка для управляемого) Emgu.TF.Lite.TfLiteInvoke.TfliteErrorHandler(int,intptr) в (оболочка, управляемая встроенной) Emgu.TF.Lite.TfLiteInvoke.tfeInterpreterInvoke(intptr) в Emgu.TF.Lite.Interpreter.Invoke () [0x00001] в C:\Personal\Ensight\Ensight.LPR.Mobile\TF\CameraTF\Emgu.TF.Lite.Shared\Interpreter.cs:75 в CameraTF.TensorflowLiteService.Recognize (цвета System.IntPtr, System.Int32 colorsCount) [0x00015] в C:\Personal\Ensight\Ensight.LPR.Mobile\TF\CameraTF\CameraTF\AR\TensorflowLiteService.cs:66 в CameraTF.CameraAccess.CameraAnalyzer.DecodeFrame (ApxLabs.FastAndroidCamera.FastJavaByteArray fastArray) [0x00175] в C:\Personal\Ensight\Ensight.LPR.Mobile\TF\CameraTF\CameraTF\Camera\CameraAnalyzer.cs:156 в CameraTF.CameraAccess25_Camera_CameraAccess25_Camera_Camera__() [0x00002] в C:\Personal\Ensight\Ensight.LPR.Mobile\TF\CameraTF\CameraTF\Camera\CameraAnalyzer.cs:114

Это исключение происходит в тот момент, когда я вызываю Invoke the Interpreter, как это сделано в этом методе:

    public void Recognize(IntPtr colors, int colorsCount)
    {
        CopyColorsToTensor(colors, colorsCount, inputTensor.DataPointer);

        interpreter.Invoke();

        var detectionBoxes = (float[])outputTensors[0].GetData();
        var detectionClasses = (float[])outputTensors[1].GetData();
        var detectionScores = (float[])outputTensors[2].GetData();
        var detectionNumDetections = (float[])outputTensors[3].GetData();

        var numDetections = (int)detectionNumDetections[0];

        Stats.NumDetections = numDetections;
        Stats.Labels = detectionClasses;
        Stats.Scores = detectionScores;
        Stats.BoundingBoxes = detectionBoxes;
    }

Это была инициализация, которая была выполнена до того, как я попытаюсь "распознать", где выделяются тензоры и подключены входы / выходы. Я подтвердил, что эта инициализация работает нормально, и я вижу свои входные и выходные слои:

    public bool Initialize(Stream modelData, bool useNumThreads, bool useNNApi)
    {
        using (var ms = new MemoryStream())
        {
            modelData.CopyTo(ms);

            model = new FlatBufferModel(ms.ToArray());
        }

        if (!model.CheckModelIdentifier())
        {
            return false;
        }

        var op = new BuildinOpResolver();
        interpreter = new Interpreter(model, op);

        interpreter.UseNNAPI(useNNApi);

        if (useNumThreads)
        {
            interpreter.SetNumThreads(Environment.ProcessorCount);
        }

        var allocateTensorStatus = interpreter.AllocateTensors();
        if (allocateTensorStatus == Status.Error)
        {
            return false;
        }

        //var input = interpreter.GetInput();
        //inputTensor = interpreter.GetTensor(input[0]);
        if (inputTensor == null)
        {
            inputTensor = interpreter.Inputs[0];
        }

        if (outputTensors == null)
        {
            outputTensors = interpreter.Outputs;
        }
        //var output = interpreter.GetOutput();
        //var outputIndex = output[0];

        //outputTensors = new Tensor[output.Length];
        //for (var i = 0; i < output.Length; i++)
        //{
        //    outputTensors[i] = interpreter.GetTensor(outputIndex + i);
        //}

        return true;
    }

Опять же, я также уверен, что это не так с остальной частью кода, такой как формирование изображения и т. Д., Поскольку я могу поменять свою модель и вставить оригинал обратно, и весь код работает. Это как-то связано с этой конкретной моделью, но я тренировался в Google Cloud и экспортировал как tflite. Я обязательно проверил различия в форме и размере ввода, и это не проблема. Я не совсем уверен, что это еще может быть, модели очень похожи. Вот метаданные экспорта, которые я получил из Google Cloud, и они выглядят довольно стандартно.

{
    "inferenceType": "QUANTIZED_UINT8", 
    "inputShape": [
        1, 
        320, 
        320, 
        3
    ], 
    "inputTensor": "normalized_input_image_tensor", 
    "maxDetections": 40, 
    "outputTensorRepresentation": [
        "bounding_boxes", 
        "class_labels", 
        "class_confidences", 
        "num_of_boxes"
    ], 
    "outputTensors": [
        "TFLite_Detection_PostProcess", 
        "TFLite_Detection_PostProcess:1", 
        "TFLite_Detection_PostProcess:2", 
        "TFLite_Detection_PostProcess:3"
    ]
}

Есть идеи или что попробовать? Благодарность!!

0 ответов

Другие вопросы по тегам