title: Unable to load tensorflow tflite model in android studio
body: <p>I have trained a TensorFlow model and convert it to TensorFlow lite using the below code:</p>
  <pre><code># Convert the model
  import tensorflow as tf
  import numpy as np
  # path to the SavedModel directory is TFLITE_PATH
  converter = tf.lite.TFLiteConverter.from_saved_model(TFLITE_PATH) 
  
  tflite_model = converter.convert()
  
  # Save the model.
  with open('model_1.tflite', 'wb') as f:
    f.write(tflite_model)
  </code></pre>
  <p>Attaching my <a href="https://drive.google.com/file/d/1sB4fPwzlyfPuDjxONv1qXlALCXCe5xih/view?usp=sharing" rel="noreferrer">model_1.tflite</a> model in case you want to investigate.
  I have tested it inside my python environment, where it is producing output using the below script:</p>
  <pre><code>import numpy as np
  import tensorflow as tf
  
  MODEL_PATH = &quot;model_1.tflite&quot;
  
  # Load TFLite model and allocate tensors.
  interpreter = tf.lite.Interpreter(model_path=MODEL_PATH)
  interpreter.allocate_tensors()
  
  # Get input and output tensors.
  input_details = interpreter.get_input_details()
  output_details = interpreter.get_output_details()
  input_shape = input_details[0]['shape']
  input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
  </code></pre>
  <h4>Print required input shape for the model</h4>
  <pre><code>print(input_shape)
  [  1 320 320   3]
  </code></pre>
  <h3>Providing input details to the interpreter</h3>
  <pre><code>interpreter.set_tensor(input_details[0]['index'], input_data)
  interpreter.invoke()
  output_data = interpreter.get_tensor(output_details[0]['index'])
  </code></pre>
  <h4>Print the output that we get from the model</h4>
  <pre><code>print(output_data)
  
  [[[0.01350823 0.02189949 0.9918406  0.9821147 ]
  [0.33122188 0.11993879 0.9528857  0.90357083]
  [0.04370229 0.13977486 0.5076436  0.9069242 ]
  [0.36508453 0.00325416 0.63923967 0.1383895 ]
  [0.12694997 0.01493323 0.4414968  0.14510964]
  [0.21113579 0.00826943 0.5027399  0.13861066]
  [0.28166008 0.9081802  0.57174915 1.0400366 ]
  [0.38398495 0.9090722  0.6709249  1.0427872 ]
  [0.561202   0.32376498 0.8054305  0.6049366 ]
  [0.3257156  0.65075576 0.43758994 0.80955625]]]
  </code></pre>
  <p>But when I am going to load it inside Android studio it is giving me the error.</p>
  <p>Note: <strong>when I downloaded a pre-trained TensorFlow model from here(<a href="https://github.com/am15h/tflite_flutter_plugin" rel="noreferrer">https://github.com/am15h/tflite_flutter_plugin</a>) and called it, it is working fine but I am unable to load my customized trained model and it is giving me the below error:</strong></p>
  <pre><code>[VERBOSE-2:dart_isolate.cc(1137)] Unhandled exception:
  Bad state: failed precondition
  #0      checkState (package:quiver/check.dart:73:5)
  #1      Tensor.setTo (package:tflite_flutter/src/tensor.dart:150:5)
  #2      Interpreter.runForMultipleInputs (package:tflite_flutter/src/interpreter.dart:194:33)
  #3      Classifier.predict (package:bewizor/tflite/classifier.dart:139:18)
  #4      IsolateUtils.entryPoint (package:bewizor/tflite/tfutils/isolate_utils.dart:45:51)
  &lt;asynchronous suspension&gt;
  </code></pre>
  <p>Below is the comparison of the output that I ran using the Netron app.</p>
  <p><a href="https://i.stack.imgur.com/371ej.png" rel="noreferrer"><img src="https://i.stack.imgur.com/371ej.png" alt="enter image description here" /></a>
  <strong>On the left-hand side, Netron view of working pre-trained model, whereas on the right-hand side, Netron view of a failed customized trained model</strong></p>
  <p>Can you please help to understand what I am lacking here and what are the things that I can try out to resolve this?</p>
  <p>Why pre-trained tflite model was working? and why not my current custom model?</p>
  <p>Is the error related to my model or the way I am calling it inside android studio should be changed?</p>
  <p>Things that I have tried out to resolve this?</p>
  <p>Try to make a model in a way to take uint8 as an input.(Idea is to make this looks like the model that is working fine but I don't think it is making an impact on model working but yes it is helpful to reduce the size of my model) Used the below code for this.</p>
  <pre><code># Convert the model
  converter = tf.lite.TFLiteConverter.from_saved_model(SAVED_MODEL_PATH) # path to the SavedModel directory
  
  converter.optimizations = [tf.lite.Optimize.DEFAULT]
  num_calibration_steps = 100
  def representative_dataset_gen():
    for _ in range(num_calibration_steps):
      input_shape = [1, 320, 320, 3]
      input_data = np.array(np.random.random_sample(input_shape), dtype=np.float32)
  
      # Get sample input data as a numpy array in a method of your choosing.
      yield [input_data]
  converter.representative_dataset = representative_dataset_gen
  converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
  converter.inference_input_type = tf.uint8  # or tf.int8
  converter.inference_output_type = tf.uint8  # or tf.int8
  converter.experimental_new_converter = False
  quantized_tflite_model = converter.convert()
  tflite_model_name = 'model_2_uint_type.tflite'
  
  if tf.__version__.startswith('1.'):
      open(tflite_model_name, &quot;wb&quot;).write(quantized_tflite_model)
  if tf.__version__.startswith('2.'):
      with open(tflite_model_name, 'wb') as f:
          f.write(quantized_tflite_model)
  </code></pre>
  <p>Also sharing .dart file code which we are using to call the model inside android studio</p>
  <pre><code>import 'dart:math';
  import 'dart:ui';
  
  import 'package:bewizor/tflite/recognition.dart';
  import 'package:flutter/material.dart';
  import 'package:image/image.dart' as imageLib;
  import 'package:tflite_flutter/tflite_flutter.dart';
  import 'package:tflite_flutter_helper/tflite_flutter_helper.dart';
  
  import 'stats.dart';
  
  /// Classifier
  class Classifier {
    /// Instance of Interpreter
    Interpreter _interpreter;
  
    /// Labels file loaded as list
    List&lt;String&gt; _labels;
  
    // static const String MODEL_FILE_NAME = &quot;tfModels/detect.tflite&quot;;
  
    static const String MODEL_FILE_NAME = &quot;tfModels/detect_new.tflite&quot;;
    static const String LABEL_FILE_NAME = &quot;tfModels/label_map.pbtxt&quot;;
  
    /// Input size of image (height = width = 300)
    static const int INPUT_SIZE = 300;
  
    /// Result score threshold
    static const double THRESHOLD = 0.5;
  
    /// [ImageProcessor] used to pre-process the image
    ImageProcessor imageProcessor;
  
    /// Padding the image to transform into square
    int padSize;
  
    /// Shapes of output tensors
    List&lt;List&lt;int&gt;&gt; _outputShapes;
  
    /// Types of output tensors
    List&lt;TfLiteType&gt; _outputTypes;
  
    /// Number of results to show
    static const int NUM_RESULTS = 5;
  
    Classifier({
      Interpreter interpreter,
      List&lt;String&gt; labels,
    }) {
      loadModel(interpreter: interpreter);
      loadLabels(labels: labels);
    }
  
    /// Loads interpreter from asset
    void loadModel({Interpreter interpreter}) async {
      try {
        _interpreter = interpreter ??
            await Interpreter.fromAsset(
              MODEL_FILE_NAME,
              options: InterpreterOptions()..threads = 4,
            );
  
        var outputTensors = _interpreter.getOutputTensors();
        _outputShapes = [];
        _outputTypes = [];
        outputTensors.forEach((tensor) {
          _outputShapes.add(tensor.shape);
          _outputTypes.add(tensor.type);
        });
      } catch (e) {
        print(&quot;Error while creating interpreter: $e&quot;);
      }
    }
  
    /// Loads labels from assets
    void loadLabels({List&lt;String&gt; labels}) async {
      try {
        _labels =
            labels ?? await FileUtil.loadLabels(&quot;assets/&quot; + LABEL_FILE_NAME);
      } catch (e) {
        print(&quot;Error while loading labels: $e&quot;);
      }
    }
  
    /// Pre-process the image
    TensorImage getProcessedImage(TensorImage inputImage) {
      padSize = max(inputImage.height, inputImage.width);
      if (imageProcessor == null) {
        imageProcessor = ImageProcessorBuilder()
            .add(ResizeWithCropOrPadOp(padSize, padSize))
            .add(ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeMethod.BILINEAR))
            .build();
      }
      inputImage = imageProcessor.process(inputImage);
      return inputImage;
    }
  
    /// Runs object detection on the input image
    Map&lt;String, dynamic&gt; predict(imageLib.Image image) {
      var predictStartTime = DateTime.now().millisecondsSinceEpoch;
  
      if (_interpreter == null) {
        print(&quot;Interpreter not initialized&quot;);
        return null;
      }
  
      var preProcessStart = DateTime.now().millisecondsSinceEpoch;
  
      // Create TensorImage from image
      TensorImage inputImage = TensorImage.fromImage(image);
  
      // Pre-process TensorImage
      inputImage = getProcessedImage(inputImage);
  
      var preProcessElapsedTime =
          DateTime.now().millisecondsSinceEpoch - preProcessStart;
  
      // // TensorBuffers for output tensors
      TensorBuffer outputLocations = TensorBufferFloat(_outputShapes[0]);
      TensorBuffer outputClasses = TensorBufferFloat(_outputShapes[1]);
      TensorBuffer outputScores = TensorBufferFloat(_outputShapes[2]);
      TensorBuffer numLocations = TensorBufferFloat(_outputShapes[3]);
  
      // Inputs object for runForMultipleInputs
      // Use [TensorImage.buffer] or [TensorBuffer.buffer] to pass by reference
      List&lt;Object&gt; inputs = [inputImage.buffer];
  
      // Outputs map
      Map&lt;int, Object&gt; outputs = {
        0: outputLocations.buffer,
        1: outputClasses.buffer,
        2: outputScores.buffer,
        3: numLocations.buffer,
      };
  
      var inferenceTimeStart = DateTime.now().millisecondsSinceEpoch;
  
      // run inference
      _interpreter.runForMultipleInputs(inputs, outputs);
  
      var inferenceTimeElapsed =
          DateTime.now().millisecondsSinceEpoch - inferenceTimeStart;
  
      // Maximum number of results to show
      int resultsCount = min(NUM_RESULTS, numLocations.getIntValue(0));
  
      // Using labelOffset = 1 as ??? at index 0
      int labelOffset = 1;
  
      // Using bounding box utils for easy conversion of tensorbuffer to List&lt;Rect&gt;
      List&lt;Rect&gt; locations = BoundingBoxUtils.convert(
        tensor: outputLocations,
        valueIndex: [1, 0, 3, 2],
        boundingBoxAxis: 2,
        boundingBoxType: BoundingBoxType.BOUNDARIES,
        coordinateType: CoordinateType.RATIO,
        height: INPUT_SIZE,
        width: INPUT_SIZE,
      );
  
      List&lt;Recognition&gt; recognitions = [];
  
      for (int i = 0; i &lt; resultsCount; i++) {
        // Prediction score
        var score = outputScores.getDoubleValue(i);
  
        // Label string
        var labelIndex = outputClasses.getIntValue(i) + labelOffset;
        var label = _labels.elementAt(labelIndex);
  
        if (score &gt; THRESHOLD) {
          // inverse of rect
          // [locations] corresponds to the image size 300 X 300
          // inverseTransformRect transforms it our [inputImage]
          Rect transformedRect = imageProcessor.inverseTransformRect(
              locations[i], image.height, image.width);
  
          recognitions.add(
            Recognition(i, label, score, transformedRect),
          );
        }
      }
  
      var predictElapsedTime =
          DateTime.now().millisecondsSinceEpoch - predictStartTime;
  
      return {
        &quot;recognitions&quot;: recognitions,
        &quot;stats&quot;: Stats(
            totalPredictTime: predictElapsedTime,
            inferenceTime: inferenceTimeElapsed,
            preProcessingTime: preProcessElapsedTime)
      };
    }
  
    /// Gets the interpreter instance
    Interpreter get interpreter =&gt; _interpreter;
  
    /// Gets the loaded labels
    List&lt;String&gt; get labels =&gt; _labels;
  }
  </code></pre>