October 25, 2024
Chicago 12, Melborne City, USA
Android

Implement MobileNetV2 model in Android give different prediction results


I am trying to implement pretrained lightweight DL model to classify image document in Android, I am getting different results between android and python, I convert the model in Tensor flow Lite in order to implement in android.

    # Load and augment training data
    train_generator = train_datagen.flow_from_directory(
        directory=train_dir,
        target_size=(224, 224),
        batch_size=32,
        class_mode="categorical",
        shuffle=True
    )

    def create_transfer_learning_model(input_shape, num_classes):
        base_model = MobileNetV2(input_shape=input_shape, include_top=False, weights="imagenet")
        base_model.trainable = False  # Freeze the pre-trained weights
    
        model = models.Sequential([
            base_model,
            layers.GlobalAveragePooling2D(),
            layers.Dense(128, activation='relu'),
            layers.Dense(num_classes, activation='softmax')
        ])
    
        return model


# Load the trained model
        model = tf.keras.models.load_model('mobilenetv2_model.h5')
        
        # Convert the model to TensorFlow Lite format
        converter = tf.lite.TFLiteConverter.from_keras_model(model)
        tflite_model = converter.convert()
        
        # Save the converted model to a .tflite file
        with open('mobilenetv2_model.tflite', 'wb') as f:
            f.write(tflite_model)

From android side I used the same image size of the image in train data

# Define input shape and number of classes
input_shape = (224, 224, 3)  # Assuming input images are resized to 224x224 RGB images
num_classes = 4  # Number of boat classes

# Create the lightweight transfer learning model
transfer_learning_model = create_transfer_learning_model(input_shape, num_classes)

# Compile the model
transfer_learning_model.compile(optimizer="adam",
                                loss="categorical_crossentropy",
                                metrics=['accuracy'])

Converting bitmap to byte array is as follows, I did not rescale (normalize) the image in android since I did not normalize the pixels in python side:

 int imageSize = 224;
    // Your model expects images of shape (224, 224, 3) where:
    // 224 is the width and height of the image.
    // 3 represents the RGB channels.
    Bitmap.createScaledBitmap(image, imageSize, imageSize, false);


private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * imageSize * imageSize * 3);
    byteBuffer.order(ByteOrder.nativeOrder());

    int[] intValues = new int[imageSize * imageSize];
    bitmap.getPixels(
            intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
  
    int pixel = 0;
    for (int i = 0; i < imageSize; i++) {
        for (int j = 0; j < imageSize; j++) {
            int val = intValues[pixel++];
            // Pass the pixel values as they are without normalization
            byteBuffer.putFloat((val >> 16) & 0xFF); // Red
            byteBuffer.putFloat((val >> 8) & 0xFF); // Green
            byteBuffer.putFloat(val & 0xFF); // Blue
        }
    }
    return byteBuffer;
}

the test database is manually captured photo’s from android devise and in paint program it has size as follows, can this make the resizing looses some of the feature and why it is give accurate result in python size although I also uses target_size=(224, 224),

enter image description here

My database looks like this:

Number of images in each class:

  • BULG_ID: 10 images
  • Congo_DrivLI: 10 images
  • MUEL_ID: 10 images
  • MUEL_PASS: 10 images



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video