title: Changes required for using non-quantized tflite files in MainActivity.java
body: <p>This <a href="https://github.com/googlecodelabs/mlkit-android/blob/master/custom-model/final/app/src/main/java/com/google/firebase/codelab/mlkit_custommodel/MainActivity.java" rel="nofollow noreferrer">MainActivity.java</a> was written for quantised models and I'm trying to use unquantised model. </p>
  
  <p>After making the changes as mentioned <a href="https://github.com/tensorflow/tensorflow/issues/14719#issuecomment-348991399" rel="nofollow noreferrer">here</a>, <a href="https://github.com/tensorflow/tensorflow/blob/25b4086bb5ba1788ceb6032eda58348f6e20a71d/tensorflow/contrib/lite/java/demo/app/src/main/java/com/example/android/tflitecamerademo/ImageClassifierFloatInception.java" rel="nofollow noreferrer">here</a> to <a href="https://github.com/googlecodelabs/mlkit-android/blob/master/custom-model/final/app/src/main/java/com/google/firebase/codelab/mlkit_custommodel/MainActivity.java" rel="nofollow noreferrer">MainActivity.java</a>, my code is</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
      private static final String TAG = "MainActivity";
      private Button mRun;
      private ImageView mImageView;
      private Bitmap mSelectedImage;
      private GraphicOverlay mGraphicOverlay;
      // Max width (portrait mode)
      private Integer mImageMaxWidth;
      // Max height (portrait mode)
      private Integer mImageMaxHeight;
      private final String[] mFilePaths =
              new String[]{"mountain.jpg", "tennis.jpg","96580.jpg"};
      /**
       * Name of the model file hosted with Firebase.
       */
      private static final String HOSTED_MODEL_NAME = "mobilenet_v1_224_quant";
      private static final String LOCAL_MODEL_ASSET = "retrained_graph_mobilenet_1_224.tflite";
      /**
       * Name of the label file stored in Assets.
       */
      private static final String LABEL_PATH = "labels.txt";
      /**
       * Number of results to show in the UI.
       */
      private static final int RESULTS_TO_SHOW = 3;
      /**
       * Dimensions of inputs.
       */
      private static final int DIM_BATCH_SIZE = 1;
      private static final int DIM_PIXEL_SIZE = 3;
      private static final int DIM_IMG_SIZE_X = 224;
      private static final int DIM_IMG_SIZE_Y = 224;
      private static final int IMAGE_MEAN = 128;
      private static final float IMAGE_STD = 128.0f;
      /**
       * Labels corresponding to the output of the vision model.
       */
      private List&lt;String&gt; mLabelList;
  
      private final PriorityQueue&lt;Map.Entry&lt;String, Float&gt;&gt; sortedLabels =
              new PriorityQueue&lt;&gt;(
                      RESULTS_TO_SHOW,
                      new Comparator&lt;Map.Entry&lt;String, Float&gt;&gt;() {
                          @Override
                          public int compare(Map.Entry&lt;String, Float&gt; o1, Map.Entry&lt;String, Float&gt;
                                  o2) {
                              return (o1.getValue()).compareTo(o2.getValue());
                          }
                      });
      /* Preallocated buffers for storing image data. */
      private final int[] intValues = new int[DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y];
      /**
       * An instance of the driver class to run model inference with Firebase.
       */
      private FirebaseModelInterpreter mInterpreter;
      /**
       * Data configuration of input &amp; output data of model.
       */
      private FirebaseModelInputOutputOptions mDataOptions;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          mGraphicOverlay = findViewById(R.id.graphic_overlay);
          mImageView = findViewById(R.id.image_view);
  
          Spinner dropdown = findViewById(R.id.spinner);
          List&lt;String&gt; items = new ArrayList&lt;&gt;();
          for (int i = 0; i &lt; mFilePaths.length; i++) {
              items.add("Image " + (i + 1));
          }
  
          ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;&gt;(this, android.R.layout
                  .simple_spinner_dropdown_item, items);
          dropdown.setAdapter(adapter);
          dropdown.setOnItemSelectedListener(this);
  
          mLabelList = loadLabelList(this);
          mRun = findViewById(R.id.button_run);
          mRun.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  runModelInference();
              }
          });
  
          int[] inputDims = {DIM_BATCH_SIZE, DIM_IMG_SIZE_X, DIM_IMG_SIZE_Y, DIM_PIXEL_SIZE};
          int[] outputDims = {DIM_BATCH_SIZE, mLabelList.size()};
          try {
              mDataOptions =
                      new FirebaseModelInputOutputOptions.Builder()
                              .setInputFormat(0, FirebaseModelDataType.FLOAT32, inputDims)
                              .setOutputFormat(0, FirebaseModelDataType.FLOAT32, outputDims)
                              .build();
              FirebaseModelDownloadConditions conditions = new FirebaseModelDownloadConditions
                      .Builder()
                      .requireWifi()
                      .build();
              FirebaseLocalModelSource localModelSource =
                      new FirebaseLocalModelSource.Builder("asset")
                              .setAssetFilePath(LOCAL_MODEL_ASSET).build();
  
              FirebaseCloudModelSource cloudSource = new FirebaseCloudModelSource.Builder
                      (HOSTED_MODEL_NAME)
                      .enableModelUpdates(true)
                      .setInitialDownloadConditions(conditions)
                      .setUpdatesDownloadConditions(conditions)  // You could also specify
                      // different conditions
                      // for updates
                      .build();
              FirebaseModelManager manager = FirebaseModelManager.getInstance();
              manager.registerLocalModelSource(localModelSource);
              manager.registerCloudModelSource(cloudSource);
              FirebaseModelOptions modelOptions =
                      new FirebaseModelOptions.Builder()
                              .setCloudModelName(HOSTED_MODEL_NAME)
                              .setLocalModelName("asset")
                              .build();
              mInterpreter = FirebaseModelInterpreter.getInstance(modelOptions);
          } catch (FirebaseMLException e) {
              showToast("Error while setting up the model");
              e.printStackTrace();
          }
      }
  
      private void runModelInference() {
          if (mInterpreter == null) {
              Log.e(TAG, "Image classifier has not been initialized; Skipped.");
              return;
          }
          // Create input data.
          ByteBuffer imgData = convertBitmapToByteBuffer(mSelectedImage, mSelectedImage.getWidth(),
                  mSelectedImage.getHeight());
  
          try {
              FirebaseModelInputs inputs = new FirebaseModelInputs.Builder().add(imgData).build();
              // Here's where the magic happens!!
              mInterpreter
                      .run(inputs, mDataOptions)
                      .addOnFailureListener(new OnFailureListener() {
                          @Override
                          public void onFailure(@NonNull Exception e) {
                              e.printStackTrace();
                              showToast("Error running model inference");
                          }
                      })
                      .continueWith(
                              new Continuation&lt;FirebaseModelOutputs, List&lt;String&gt;&gt;() {
                                  @Override
                                  public List&lt;String&gt; then(Task&lt;FirebaseModelOutputs&gt; task) {
                                      float[][] labelProbArray = task.getResult()
                                              .&lt;float[][]&gt;getOutput(0);
                                      List&lt;String&gt; topLabels = getTopLabels(labelProbArray);
                                      mGraphicOverlay.clear();
                                      GraphicOverlay.Graphic labelGraphic = new LabelGraphic
                                              (mGraphicOverlay, topLabels);
                                      mGraphicOverlay.add(labelGraphic);
                                      return topLabels;
                                  }
                              });
          } catch (FirebaseMLException e) {
              e.printStackTrace();
              showToast("Error running model inference");
          }
  
      }
  
      /**
       * Gets the top labels in the results.
       */
      private synchronized List&lt;String&gt; getTopLabels(float[][] labelProbArray) {
          for (int i = 0; i &lt; mLabelList.size(); ++i) {
              sortedLabels.add(
                      new AbstractMap.SimpleEntry&lt;&gt;(mLabelList.get(i), (labelProbArray[0][i] )));
              if (sortedLabels.size() &gt; RESULTS_TO_SHOW) {
                  sortedLabels.poll();
              }
          }
          List&lt;String&gt; result = new ArrayList&lt;&gt;();
          final int size = sortedLabels.size();
          for (int i = 0; i &lt; size; ++i) {
              Map.Entry&lt;String, Float&gt; label = sortedLabels.poll();
              result.add(label.getKey() + ":" + label.getValue());
          }
          Log.d(TAG, "labels: " + result.toString());
          return result;
      }
  
      /**
       * Reads label list from Assets.
       */
      private List&lt;String&gt; loadLabelList(Activity activity) {
          List&lt;String&gt; labelList = new ArrayList&lt;&gt;();
          try (BufferedReader reader =
                       new BufferedReader(new InputStreamReader(activity.getAssets().open
                               (LABEL_PATH)))) {
              String line;
              while ((line = reader.readLine()) != null) {
                  labelList.add(line);
              }
          } catch (IOException e) {
              Log.e(TAG, "Failed to read label list.", e);
          }
          return labelList;
      }
  
      /**
       * Writes Image data into a {@code ByteBuffer}.
       */
      private synchronized ByteBuffer convertBitmapToByteBuffer(
              Bitmap bitmap, int width, int height) {
          ByteBuffer imgData =
                  ByteBuffer.allocateDirect(
                         4*DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
  
          imgData.order(ByteOrder.nativeOrder());
          Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, DIM_IMG_SIZE_X, DIM_IMG_SIZE_Y,
                  true);
          imgData.rewind();
          scaledBitmap.getPixels(intValues, 0, scaledBitmap.getWidth(), 0, 0,
                  scaledBitmap.getWidth(), scaledBitmap.getHeight());
          // Convert the image to int points.
          int pixel = 0;
          for (int i = 0; i &lt; DIM_IMG_SIZE_X; ++i) {
              for (int j = 0; j &lt; DIM_IMG_SIZE_Y; ++j) {
                  final int val = intValues[pixel++];
                  imgData.putFloat((((val &gt;&gt; 16) &amp; 0xFF)-IMAGE_MEAN)/IMAGE_STD);
                  imgData.putFloat((((val &gt;&gt; 8) &amp; 0xFF)-IMAGE_MEAN)/IMAGE_STD);
                  imgData.putFloat(((val &amp; 0xFF)-IMAGE_MEAN)/IMAGE_STD);
  
  
              }
          }
          return imgData;
      }
  
      private void showToast(String message) {
          Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
      }
  
      public void onItemSelected(AdapterView&lt;?&gt; parent, View v, int position, long id) {
          mGraphicOverlay.clear();
          mSelectedImage = getBitmapFromAsset(this, mFilePaths[position]);
          if (mSelectedImage != null) {
              // Get the dimensions of the View
              Pair&lt;Integer, Integer&gt; targetedSize = getTargetedWidthHeight();
  
              int targetWidth = targetedSize.first;
              int maxHeight = targetedSize.second;
  
              // Determine how much to scale down the image
              float scaleFactor =
                      Math.max(
                              (float) mSelectedImage.getWidth() / (float) targetWidth,
                              (float) mSelectedImage.getHeight() / (float) maxHeight);
  
              Bitmap resizedBitmap =
                      Bitmap.createScaledBitmap(
                              mSelectedImage,
                              (int) (mSelectedImage.getWidth() / scaleFactor),
                              (int) (mSelectedImage.getHeight() / scaleFactor),
                              true);
  
              mImageView.setImageBitmap(resizedBitmap);
              mSelectedImage = resizedBitmap;
          }
      }
  
      @Override
      public void onNothingSelected(AdapterView&lt;?&gt; parent) {
          // Do nothing
      }
  
      // Utility functions for loading and resizing images from app asset folder.
      public static Bitmap getBitmapFromAsset(Context context, String filePath) {
          AssetManager assetManager = context.getAssets();
  
          InputStream is;
          Bitmap bitmap = null;
          try {
              is = assetManager.open(filePath);
              bitmap = BitmapFactory.decodeStream(is);
          } catch (IOException e) {
              e.printStackTrace();
          }
  
          return bitmap;
      }
  
      // Returns max image width, always for portrait mode. Caller needs to swap width / height for
      // landscape mode.
      private Integer getImageMaxWidth() {
          if (mImageMaxWidth == null) {
              // Calculate the max width in portrait mode. This is done lazily since we need to
              // wait for a UI layout pass to get the right values. So delay it to first time image
              // rendering time.
              mImageMaxWidth = mImageView.getWidth();
          }
  
          return mImageMaxWidth;
      }
  
      // Returns max image height, always for portrait mode. Caller needs to swap width / height for
      // landscape mode.
      private Integer getImageMaxHeight() {
          if (mImageMaxHeight == null) {
              // Calculate the max width in portrait mode. This is done lazily since we need to
              // wait for a UI layout pass to get the right values. So delay it to first time image
              // rendering time.
              mImageMaxHeight =
                      mImageView.getHeight();
          }
  
          return mImageMaxHeight;
      }
  
      // Gets the targeted width / height.
      private Pair&lt;Integer, Integer&gt; getTargetedWidthHeight() {
          int targetWidth;
          int targetHeight;
          int maxWidthForPortraitMode = getImageMaxWidth();
          int maxHeightForPortraitMode = getImageMaxHeight();
          targetWidth = maxWidthForPortraitMode;
          targetHeight = maxHeightForPortraitMode;
          return new Pair&lt;&gt;(targetWidth, targetHeight);
      }
  }
  </code></pre>
  
  <p>But I'm still getting <code>Failed to get input dimensions. 0-th input should have 268203 bytes, but found 1072812 bytes</code> for inception and <code>0-th input should have 150528 bytes, but found 602112 bytes</code> for mobilenet. So, a factor is <code>4</code> there always.</p>
  
  <p>To see what I've changed, the output of <code>diff original.java changed.java</code> is: (Ignore the line numbers)</p>
  
  <pre><code>32a33,34
  &gt;     private static final int IMAGE_MEAN = 128;
  &gt;     private static final float IMAGE_STD = 128.0f;
  150,151c152,153
  &lt;                                     byte[][] labelProbArray = task.getResult()
  &lt;                                             .&lt;byte[][]&gt;getOutput(0);
  ---
  &gt;                                     float[][] labelProbArray = task.getResult()
  &gt;                                             .&lt;float[][]&gt;getOutput(0);
  170c172
  &lt;     private synchronized List&lt;String&gt; getTopLabels(byte[][] labelProbArray) {
  ---
  &gt;     private synchronized List&lt;String&gt; getTopLabels(float[][] labelProbArray) {
  173,174c175
  &lt;                     new AbstractMap.SimpleEntry&lt;&gt;(mLabelList.get(i), (labelProbArray[0][i] &amp;
  &lt;                             0xff) / 255.0f));
  ---
  &gt;                     new AbstractMap.SimpleEntry&lt;&gt;(mLabelList.get(i), (labelProbArray[0][i] )));
  214c215,216
  &lt;                         DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
  ---
  &gt;                        4*DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
  &gt; 
  226,228c228,232
  &lt;                 imgData.put((byte) ((val &gt;&gt; 16) &amp; 0xFF));
  &lt;                 imgData.put((byte) ((val &gt;&gt; 8) &amp; 0xFF));
  &lt;                 imgData.put((byte) (val &amp; 0xFF));
  ---
  &gt;                 imgData.putFloat((((val &gt;&gt; 16) &amp; 0xFF)-IMAGE_MEAN)/IMAGE_STD);
  &gt;                 imgData.putFloat((((val &gt;&gt; 8) &amp; 0xFF)-IMAGE_MEAN)/IMAGE_STD);
  &gt;                 imgData.putFloat(((val &amp; 0xFF)-IMAGE_MEAN)/IMAGE_STD);
  </code></pre>