Search code examples
tensorflowtensorflow.jstensorflowjs-convertermobilenet

Image Classification Graph model making wrong predictions


I'm using the make_image_classifier python script to retrain a mobilenetv2 on a new set of images. My end goal is to make predictions in tfjs in the browser.

This is exactly what i'm doing:

Step 1: Retrain the model

make_image_classifier \
  --image_dir input_data \
  --tfhub_module https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4 \
  --image_size 224 \
  --saved_model_dir ./trained_model \
  --labels_output_file class_labels.txt \
  --tflite_output_file new_mobile_model.tflite

Step 2: Convert the tf saved model to a graph model using tensorflowjs_converter

tensorflowjs_converter \
    --input_format=tf_saved_model \
    --output_format=tfjs_graph_model \
    --signature_name=serving_default \
    --saved_model_tags=serve \
    trained_model/ \
    web_model/

Step 3: load the new model in the browser, preprocess an image input and ask the model to make a prediction

const model =  tf.loadGraphModel('model.json').then(function(m){
var img = document.getElementById("img");
var processed=preprocessImage(img, "mobilenet")
    window.prediction=m.predict(processed)
        window.prediction.print();
    })
})

function preprocessImage(image,modelName){
    let tensor=tf.browser.fromPixels(image)
    .resizeNearestNeighbor([224,224])
    .toFloat();
    console.log('tensor pro', tensor);
    if(modelName==undefined)
    {
        return tensor.expandDims();
    }
    if(modelName=="mobilenet")
    {
        let offset=tf.scalar(127.5);
        console.log('offset',offset);
        return tensor.sub(offset)
        .div(offset)
        .expandDims();
    }
    else
    {
        throw new Error("Unknown Model error");
    }
}

I'm getting invalid results. I checked the predictions made by the initial model and they are correct so what I'm thinking is either the conversion is not happening properly or I'm not preprocessing the image in the same manner that the initial script is.

Help.

P.S: When running the converter, I'm getting the following message. Not sure if its directly relevant to what I'm experiencing.

tensorflow/core/graph/graph_constructor.cc:750 Node 'StatefulPartitionedCall' has 71 outputs but the _output_shapes attribute specifies shapes for 605 outputs. Output shapes may be inaccurate.


Solution

  • make_image_classifier creates a saved_model specified to tensorflow lite. If you rather want to convert mobilenet to tensorflow.js, the command to used has been given in this answer.

    Instead of using make_image_classifier, you would need to use retrain.py which can be downloded by the following

    curl -LO https://github.com/tensorflow/hub/raw/master/examples/image_retraining/retrain.py