Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A model with empty weights doesn't load #7865

Closed
thekevinscott opened this issue Jul 20, 2023 · 13 comments
Closed

A model with empty weights doesn't load #7865

thekevinscott opened this issue Jul 20, 2023 · 13 comments
Assignees

Comments

@thekevinscott
Copy link
Contributor

thekevinscott commented Jul 20, 2023

System information

  • Have I written custom code (as opposed to using a stock example script provided in TensorFlow.js): Yes
  • OS Platform and Distribution (e.g., Linux Ubuntu 16.04): Mac
  • TensorFlow.js installed from (npm or script link): npm
  • TensorFlow.js version (use command below): 4.8.0

Describe the current behavior
A model.json with an empty array of weights fails to be loaded:

$ tf.loadLayersModel('/path/to/my/model');
        var key = Object.keys(weights)[0].split('/');
                                         ^
TypeError: Cannot read properties of undefined (reading 'split')

Why would I want a model with empty weights?

I maintain a tool, UpscalerJS, for doing image upscaling in Javascript. It has a number of integration tests that require a functioning Tensorflow.js model, and it's helpful to keep that model as simple possible (a single upsampling layer) to assert behavior without significant test latency.

At some point tests were working, but a version upgrade somewhere along the line broke things. I haven't yet been able to isolate the version things changed.

Describe the expected behavior

I would expect a model with an empty weights array to load.

Standalone code to reproduce the issue

https://codesandbox.io/p/sandbox/jolly-firefly-2g63jk

Or, run the following code in Node:

const tf = require("@tensorflow/tfjs-node");
const fs = require("fs");

(async () => {
  const modelPath = `/${__dirname}/model`;
  const modelPathWithFile = `file://${modelPath}`;
  if (!fs.existsSync(modelPath)) {
    const model = tf.sequential();
    const scale = 2;
    model.add(
      tf.layers.upSampling2d({
        size: [scale, scale],
        dataFormat: "channelsLast",
        inputShape: [null, null, 3],
      })
    );

    model.compile({ loss: "meanSquaredError", optimizer: "sgd" });

    await model.save(modelPathWithFile);
  }

  await tf.loadLayersModel(`${modelPathWithFile}/model.json`);
})();
@thekevinscott thekevinscott added the type:bug Something isn't working label Jul 20, 2023
@gaikwadrahul8 gaikwadrahul8 self-assigned this Jul 20, 2023
@gaikwadrahul8
Copy link
Contributor

gaikwadrahul8 commented Jul 20, 2023

Hi, @thekevinscott

Thank you for bringing this issue to our attention and I tried to replicate the same issue from my end and I'm also getting the same error message which you've mentioned above.

If I'm not wrong model with empty weights won't load in TFJs because TFJs uses the weights to initialize the model layers. If the weights are empty, the layers won't be initialized and the model won't be able to load or run

Here is output from above code snippet for reference :

gaikwadrahul-macbookpro:test-7865 gaikwadrahul$ node index.js
/Users/gaikwadrahul/Desktop/TFJS/test-7865/node_modules/@tensorflow/tfjs-layers/dist/tf-layers.node.js:21666
        var key = Object.keys(weights)[0].split('/');
                                         ^

TypeError: Cannot read properties of undefined (reading 'split')
    at Container.loadWeights (/Users/gaikwadrahul/Desktop/TFJS/test-7865/node_modules/@tensorflow/tfjs-layers/dist/tf-layers.node.js:21666:42)
    at /Users/gaikwadrahul/Desktop/TFJS/test-7865/node_modules/@tensorflow/tfjs-layers/dist/tf-layers.node.js:25621:27
    at step (/Users/gaikwadrahul/Desktop/TFJS/test-7865/node_modules/@tensorflow/tfjs-layers/dist/tf-layers.node.js:159:27)
    at Object.next (/Users/gaikwadrahul/Desktop/TFJS/test-7865/node_modules/@tensorflow/tfjs-layers/dist/tf-layers.node.js:108:53)
    at fulfilled (/Users/gaikwadrahul/Desktop/TFJS/test-7865/node_modules/@tensorflow/tfjs-layers/dist/tf-layers.node.js:89:28)

Node.js v18.15.0
gaikwadrahul-macbookpro:test-7865 gaikwadrahul$ 

I tried to load model.json file in https://netron.app/ and I got below output :

image

@thekevinscott
Copy link
Contributor Author

thekevinscott commented Jul 20, 2023

Thanks for the feedback, @gaikwadrahul8

If I create the model and run a prediction through it, it works:


const t = tf.ones([1, 2,2,3]);
const prediction = model.predict(t)
// prediction has shape [1,4,4,3]

So it looks like a model can have empty weights if it’s created on the fly, but it can’t be loaded from a file.

@gaikwadrahul8
Copy link
Contributor

@thekevinscott

You're welcome and you understood correctly and I have edited my above comment where I loaded model.json file in https://netron.app/ to see model topology.

If you don't need further assistance on this issue, Could you please confirm if this issue is resolved for you ? Please feel free to close the issue if it is resolved ? Thank you!

@thekevinscott
Copy link
Contributor Author

The point I was trying to make above is that creating a model on the fly with empty weights works and successfully runs on an input.

Saving that model and reloading it fails.

I would expect the behavior to be identical for both cases. Either both work, or both fail. Or is there a reason that loaded models exhibit different behavior?

@thekevinscott
Copy link
Contributor Author

thekevinscott commented Jul 21, 2023

It appears the change was introduced in version 4.9.x. Version 4.8.x loads a model with empty weights fine.

Here is a code sandbox pinned to 4.8.x demonstrating the previous working behavior:

https://codesandbox.io/p/sandbox/admiring-snow-5hvhkl?file=%2Findex.js%3A1%2C1

The model loads and is able to run inference against a given tensor.

@thekevinscott
Copy link
Contributor Author

Here is the change that introduced the behavior: 97cb1ff#diff-9279ae16c497b4a3d6660978362e8225dd135951408da17adddc65df2e9acff7R599

@gaikwadrahul8
Copy link
Contributor

Hi, @thekevinscott

Thank you for your analysis and pointing out the root cause for this issue with @tensorflow/tfjs-node": "^4.9.0 and I also tested the code with @tensorflow/tfjs-node": "^4.8.0 it's loading and doing the inference so would you like to submit the PR to take care of this issue from your end if you've workaround ? or else our concerned team will take look into this issue and will fix this issue soon.

Thank you for noticing this issue with @tensorflow/tfjs-node": "^4.9.0, I really appreciate your valuable time and efforts. Thank you!

@thekevinscott
Copy link
Contributor Author

Sure thing I'll take a look

@thekevinscott
Copy link
Contributor Author

Opened PR #7868

@gaikwadrahul8
Copy link
Contributor

Hi, @thekevinscott

Thank you for submitting the PR, Team will review your PR and will take appropriate action from their end. Thank you!

@gaikwadrahul8
Copy link
Contributor

Hi, @thekevinscott

I see your this PR #7868 got merged to take care of this issue so could you please check from your end let us know, is it working as expected with @tensorflow/tfjs-node": "^4.9.0 or not ?

If it's working as expected, please feel free to close this issue if it is resolved. Thank you!

@thekevinscott
Copy link
Contributor Author

4.9.0 was released on July 19 so, no, the fix is not yet published (I assume it will land in 4.11.0) but yes I'm happy to close this issue as resolved.

@google-ml-butler
Copy link

Are you satisfied with the resolution of your issue?
Yes
No

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants