patlevin / tfjs-to-tf

A TensorFlow.js Graph Model Converter
MIT License
139 stars 18 forks source link

convert bodypix js model to pb . then convert pb to tflite #32

Closed HHMedic closed 3 years ago

HHMedic commented 3 years ago

Hello. I wanna convert bodypix js model to pb . then convert pb to tflite.

step1: down model

· Download the model.json file from https://storage.googleapis.com/tfjs-models/savedmodel/bodypix/resnet50/float/model-stride16.json.

· Download Corresponding weights from https://storage.googleapis.com/tfjs-models/savedmodel/bodypix/resnet50/float/group1-shard1of23.bin ... https://storage.googleapis.com/tfjs-models/savedmodel/bodypix/resnet50/float/group1-shard23of23.bin

step2. convert pb file run the script : tfjs_graph_converter /Users/hh/Desktop/model /Users/hh/Desktop/model/model.pb then I get the model.pb in folder. then rename model.pb to saved_model.pb

step3. convert tflite file run the script : tflite_convert --output_file /Users/hh/Desktop/model/model.tflite --graph_def_file /Users/hh/Desktop/model/saved_model.pb --saved_model_dir /Users/hh/Desktop/model

then get the error tip: RuntimeError: MetaGraphDef associated with tags {'serve'} could not be found in SavedModel. To inspect available tag-sets in the SavedModel, please use the SavedModel CLI: saved_model_cli available_tags: [].

which step cause error?

patlevin commented 3 years ago

which step cause error?

Step 2 is the problem.

You are telling the tflite converter that you want to convert a saved_model, but in Step 2 you are generating a frozen model. These are not the same and you must not rename model.pb to saved_model.pb - that's not changing anything.

If you want to convert a saved_model to tflite, you must convert to a saved_model instead and Step 2 becomes:

mkdir -p /Users/hh/Desktop/saved_model
tfjs_graph_converter --output_format tf_saved_model /Users/hh/Desktop/model /Users/hh/Desktop/saved_model

and Step 3 accordingly:

tflite_convert --output_file /Users/hh/Desktop/model/model.tflite --saved_model_dir /Users/hh/Desktop/save_model

This should work as intended.

HHMedic commented 3 years ago

Thanks @patlevin . now I got .tflite file successful .

but. do you have any idea about how use this .tflite in Android application.

I have read an example at https://github.com/hegman12/body_pix_tflite . but this example is base on MobilenetV1 float32.

and my model is base on resnet50.

patlevin commented 3 years ago

@HHMedic while I'm usually not the right person to ask model-specific questions, I can answer this one.

The only difference between the MobilenetV1 version and the resnet50 variant is the pre-processing.

MobilenetV1 requires normalised input (e.g. pixel values converted to float in the range [-1, 1]), whereas resnet50 expects pixel values in the range [0, 255].

The pixel values also need to be normalised, but with resnet50 you need to add the image mean RGB-vector, which is [-123.15, -115.90, -103.06]. This means you would need to make some small changes to the classes BodyPixPlugin and Converter.

First you could add a new parameter to Converter.bitmapToByteBuffer by adding the RGB-vector:

public static ByteBuffer bitmapToByteBuffer(Bitmap image, DataType targetType, int channels, float[] mean){

Then during the conversion, you can add the resnet50 image mean (same method, here):

              imgData.putFloat(((pixelValue >> 16) & 0xFF) + mean[0]) ;
              imgData.putFloat(((pixelValue >> 8) & 0xFF) + mean[1]) ;
              imgData.putFloat((pixelValue & 0xFF) + mean[2]);

In the plugin class,line 168 becomes something like:

    float[] resnet50mean = { -123.15, -115.90, -103.06 };
    return Converter.bitmapToByteBuffer(image.getBitmap(),DataType.FLOAT32,3, resnet50mean);

Of course you could also not change the parameters of the method bitmapToByteBuffer and hardcode the image mean directly, but the additional parameter gives you the flexibility to use the MobilenetV1 model, too by just passing [0.0, 0.0, 0.0] as the image mean.

Anyway, that should do the trick and the rest of the code would work same with the resnet50 model.

Good luck!

HHMedic commented 3 years ago

@patlevin Thanks a lot for your knowledge. I will try soon.

HHMedic commented 3 years ago

Hi @patlevin . I have some change with code follow your suggestion.

unfortunatly. occured another issue. I have open a new issue for body_pix_tflite project.

You can join the discuss. https://github.com/hegman12/body_pix_tflite/issues/10