tensorflow / tfjs

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

Quick Question on Transferring Model Weights #8382

Open TheRealCasmat opened 1 month ago

TheRealCasmat commented 1 month ago

Hey!

In the TFJS API, there is a getWeights() fcn that returns a tensor containing the weights of the model. I tried converting this tensor into a json and send that to a python server containing TensorFlow and tried loading the weights, but I was unable to get the format of the weights to work. Any idea how I am able to transfer model weights from TFJS to TF?

Thanks!

shmishra99 commented 1 month ago

Hi @TheRealCasmat ,

TFJS and tensorflow use distinct weight formats. In tfjs, weights are represented as tf.tensors, while in TensorFlow, they're primarily stored as NumPy arrays. To seamlessly transfer weights between these platforms, you'll need to convert the format accordingly. It's generally not possible to directly set tfjs weights using TensorFlow's model.set_weights() function.

Thank you!!

TheRealCasmat commented 1 month ago

Hey @shmishra99!

Yes, they’re different formats, but how do I convert the formats?

Thanks!

TheRealCasmat commented 1 month ago

Hey!

Any ideas?

Thanks!

shmishra99 commented 1 month ago

HI @TheRealCasmat ,

Apologies for the delayed response. In tjfs or tensorFlow, there isn't a any API or function available specifically to convert only tfjs model weights to tensorFlow weights.

While thetfjs-converter is available, it will convert the entire tfjs model to a tensorFlow model. If you need to convert the tfjs weights only separately, you'll need to create your own custom logic to accomplish this.

Thank You!!

TheRealCasmat commented 1 month ago

Hey @shmishra99!

No worries, I was trying to work out the logic of the conversion, but I couldn’t completely nail it down and was wondering if you’d be able to help. Here’s what I had so far:

In my react frontend using axios:

      const weights = model.getWeights(true);

      const serializedWeights = weights.map((tensor) => tensor.arraySync());
      const weightShapes = weights.map((tensor) => tensor.shape);

      const payload = {
        weights: serializedWeights,
        shapes: weightShapes,
      };

      const response = await axios.post(
        "https://api.website.com/update",
        payload,
      );

Flask backend:


@app.route("/update", methods=["POST"])
def update():
    try:
        data = request.json

        weights = data["weights"]
        shapes = data["shapes"]

        model_weights = [np.array(w).reshape(s) for w, s in zip(weights, shapes)]

        model.set_weights(model_weights)
        model.save('models/keras/fla_model.h5')

        tfjs.converters.dispatch_keras_h5_to_tfjs_layers_model_conversion('models/keras/fla_model.h5', 'models/tfjs/')

Thanks!

shmishra99 commented 1 month ago

Hi @TheRealCasmat ,

I was trying to convert the tfjs weights to tensorflow weights, but it is a very complex task, and I am unable to set the weights in the tensorflow model. Can we try converting the tfjs model to a keras model and then transfer the whole model to a backend API, so we can fetch the weights on the backend?

Thank You!!

TheRealCasmat commented 1 month ago

Hey @shmishra99!

Yeah that wouldn’t be ideal, I was trying to implement federated learning so only the modified weights of a users local model would be sent to a global model and updated there. If the tfjs converter is able to convert the models to keras, wouldn’t some code in the repo manage the weight conversion itself? I couldn’t find anything on it however..

Thanks!

TheRealCasmat commented 1 month ago

Any Ideas?