tensorflow / tfjs

A WebGL accelerated JavaScript library for training and deploying ML models.
https://js.tensorflow.org
Apache License 2.0
18.47k stars 1.93k forks source link

Make tensorflow.estimator saved_models tfjs-node compatible #4160

Closed santiher closed 3 years ago

santiher commented 4 years ago

System information

Describe the feature and the current behavior/state.

There are a bunch of estimators easy to use and fit implemented in tf.estimators, like BoostedTreesClassifiers or LinearClassifier. But when one tries to load a model saved in tfjs-node it will fail due to unregistered operations, e.g.:

Error: Failed to load SavedModel: Op type not registered 'ParseExampleV2' in binary running on ...

Can the missing operations required for canned tensorflow estimators be implemented?

Will this change the current api? How?

No.

Who will benefit with this feature?

Anybody wanting to deploy a good model for arbitrary tasks quickly in Node.js.

rthadur commented 4 years ago

cc @pyu10055 @tafsiri

pyu10055 commented 4 years ago

@santiher have you tried to run the TF saved model directly within node? steps are outline here.

santiher commented 4 years ago

Hi, thanks for the responses.

@pyu10055, yes I tried using the TF saved model directly within node, I tried this minimal thing:

import * as tf from '@tensorflow/tfjs-node';

async function main() {
  const model = await tf.node.loadSavedModel('models/1604014122');
  console.log(model)
}

main()
  .then(() => {
    process.exit(0);
  })
  .catch((error) => {
    console.log(error);
    process.exit(2);
  });

and different variations and get this logs:

2020-10-30 15:03:41.916844: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-10-30 15:03:41.947675: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 3193905000 Hz
2020-10-30 15:03:41.948099: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x55ae24afe190 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-10-30 15:03:41.948115: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
2020-10-30 15:03:41.997761: I tensorflow/cc/saved_model/reader.cc:31] Reading SavedModel from: /data/gitlab/every/every.org/models/notebooks/models/amongus/1604014122
2020-10-30 15:03:41.998221: I tensorflow/cc/saved_model/reader.cc:54] Reading meta graph with tags { serve }
2020-10-30 15:03:42.003493: I tensorflow/cc/saved_model/loader.cc:311] SavedModel load for tags { serve }; Status: fail. Took 5732 microseconds.

Error: Failed to load SavedModel: Op type not registered 'ParseExampleV2' in binary running on macaligo. Make sure the Op and Kernel are registered in the binary running in this process. Note that if you are loading a saved graph which used ops from tf.contrib, accessing (e.g.) `tf.contrib.resampler` should be done before importing the graph, as contrib ops are lazily registered when the module is first accessed.
    at NodeJSKernelBackend.loadSavedModelMetaGraph (/data/gitlab/every/every.org/models/notebooks/models/jsattempt/node_modules/@tensorflow/tfjs-node/dist/nodejs_kernel_backend.js:1484:29)
    at Object.<anonymous> (/data/gitlab/every/every.org/models/notebooks/models/jsattempt/node_modules/@tensorflow/tfjs-node/dist/saved_model.js:446:45)
    at step (/data/gitlab/every/every.org/models/notebooks/models/jsattempt/node_modules/@tensorflow/tfjs-node/dist/saved_model.js:48:23)
    at Object.next (/data/gitlab/every/every.org/models/notebooks/models/jsattempt/node_modules/@tensorflow/tfjs-node/dist/saved_model.js:29:53)
    at fulfilled (/data/gitlab/every/every.org/models/notebooks/models/jsattempt/node_modules/@tensorflow/tfjs-node/dist/saved_model.js:20:58)

I generated the model in Python doing something like:

# Define estimator
feature_columns = [
    tf.feature_column.numeric_column('position'),
    tf.feature_column.categorical_column_with_hash_bucket(
        'color', 10, dtype=tf.dtypes.string
    ),
]
estimator = estimator_trees_among_us = tf.estimator.BoostedTreesClassifier(feature_columns)

# Train
estimator = estimator.train(lambda: (X_train, y_train))

# Save
serving_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(
    tf.feature_column.make_parse_example_spec(feature_columns)
)
saved_path = estimator.export_saved_model(export_path, serving_input_fn)
print(saved_path)

I also tried with ts.estimator.LinearClassifier and just numeric columns without success. Loading and using the model in Python worked.

pyu10055 commented 4 years ago

@santiher parseExampleV2 are not part of the TF core c++ API, unfortunately that is what TFJS node based upon. you can avoid using it as the signature of the saved model by avoiding using it in the serving_input_fn

serving_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(
    tf.feature_column.make_parse_example_spec(feature_columns)
google-ml-butler[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you.

santiher commented 3 years ago

I tried doing it without make_parse_example_spec without success. The tf.io.FixedLenFeature or tf.io.VarLenFeature returned by that function are the problem and I didn't manage to save the model without them.

I guess that for now I'll be using the keras api to build a linear model or neural network.

google-ml-butler[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you.

google-ml-butler[bot] commented 3 years ago

Closing as stale. Please @mention us if this needs more attention.