ml5js / ml5-library

Friendly machine learning for the web! 🤖
https://ml5js.org
Other
6.38k stars 906 forks source link

model topology missing handpose regression #1479

Open j3nsykes opened 3 months ago

j3nsykes commented 3 months ago

Dear ml5 community,

I'm submitting a new issue. Please see the details below.

→ Step 1:

I am using HandPose.js and ML5 neural net function to train a regression model. This works well and predict outputs as expected. However, I am now saving the model and trying to preload it so it can be run without the need to train every time. The Save function works and provides me with 3 files. Yet when i load these files I get a 'modelTopology field is missing from file model.json' console error. When i check the model.json file the topology is there. Is it a case that the naming structure for handpose is not [sequential]? or perhaps a ML5 version issue? I am using https://unpkg.com/ml5@0.20.0-alpha.3/dist/ml5.js

→ Step 2: Screenshots

Screenshot 2024-02-22 at 15 04 47 Screenshot 2024-02-22 at 15 05 02 Screenshot 2024-02-22 at 15 05 09

→ Step 3: Share an example of the issue 🦄

Here's some example code

Other relevant information, if applicable

→ Describe your setup 🦄

Here's some helpful information about my setup...

j3nsykes commented 3 months ago

I have narrowed this down to the model.json array structure being structured differently on .save() with latest alpha releases. I have to step back to version ml5@0.4.3 to get the model load() function to work but of course this is not compatible with the latest ml5.hand.pose Is there a fix that can be made to the json array structure so load() will work with the later alpha versions of ml5?

j3nsykes commented 3 months ago

JSON structure for version 0.4.3

{"modelTopology":{
  "class_name":"Sequential",
  "config":[{"class_name":"Dense","config":{"units":16,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense1","trainable":true,"batch_input_shape":[null,2],"dtype":"float32"}},{"class_name":"Dense","config":{"units":1,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense2","trainable":true}}],"keras_version":"tfjs-layers 1.2.2","backend":"tensor_flow.js"},"weightsManifest":[{"paths":["./model.weights.bin"],"weights":[{"name":"dense_Dense1/kernel","shape":[2,16],"dtype":"float32"},{"name":"dense_Dense1/bias","shape":[16],"dtype":"float32"},{"name":"dense_Dense2/kernel","shape":[16,1],"dtype":"float32"},{"name":"dense_Dense2/bias","shape":[1],"dtype":"float32"}]}]}
j3nsykes commented 3 months ago

model.JSON for later versions

{
  "modelTopology": {
    "class_name": "Sequential",
    "config": {
      "name": "sequential_1",
      "layers": [
        {
          "class_name": "Dense",
          "config": {
            "units": 16,
            "activation": "relu",
            "use_bias": true,
            "kernel_initializer": {
              "class_name": "VarianceScaling",
              "config": {
                "scale": 1,
                "mode": "fan_avg",
                "distribution": "normal",
                "seed": null
              }
            },
            "bias_initializer": { "class_name": "Zeros", "config": {} },
            "kernel_regularizer": null,
            "bias_regularizer": null,
            "activity_regularizer": null,
            "kernel_constraint": null,
            "bias_constraint": null,
            "name": "dense_Dense1",
            "trainable": true,
            "batch_input_shape": [null, 42],
            "dtype": "float32"
          }
        },
        {
          "class_name": "Dense",
          "config": {
            "units": 1,
            "activation": "sigmoid",
            "use_bias": true,
            "kernel_initializer": {
              "class_name": "VarianceScaling",
              "config": {
                "scale": 1,
                "mode": "fan_avg",
                "distribution": "normal",
                "seed": null
              }
            },
            "bias_initializer": { "class_name": "Zeros", "config": {} },
            "kernel_regularizer": null,
            "bias_regularizer": null,
            "activity_regularizer": null,
            "kernel_constraint": null,
            "bias_constraint": null,
            "name": "dense_Dense2",
            "trainable": true
          }
        }
      ]
    },
    "keras_version": "tfjs-layers 4.8.0",
    "backend": "tensor_flow.js"
  },
  "weightsManifest": [
    {
      "paths": ["./model.weights.bin"],
      "weights": [
        {
          "name": "dense_Dense1/kernel",
          "shape": [42, 16],
          "dtype": "float32"
        },
        { "name": "dense_Dense1/bias", "shape": [16], "dtype": "float32" },
        { "name": "dense_Dense2/kernel", "shape": [16, 1], "dtype": "float32" },
        { "name": "dense_Dense2/bias", "shape": [1], "dtype": "float32" }
      ]
    }
  ]
}
j3nsykes commented 3 months ago

So you can see config is structured differently.

j3nsykes commented 3 months ago

Although to note: the newer JSON structure works fine with classification and can be saved and loaded without issue. Its only regression i am seeing this error

j3nsykes commented 3 months ago

This is definitely specific to https://unpkg.com/ml5@0.20.0-alpha.3/dist/ml5.js

I can now run the regression training, saving and loading with 'https://unpkg.com/ml5@latest/dist/ml5.min.js'

lindapaiste commented 3 months ago

Looks like the 0.4.3 version stores the array of layers as the modelTopology.config property, whereas in the newer version it is modelTopology.config.layers. This may have been a change in how TFJS saves the file. We would want to support legacy files which were trained under the old version.

The specific error message "modelTopology field is missing from file model.json" is odd though. It makes me wonder if we are passing it to TFJS incorrectly. Like passing a portion of the object rather than the whole object. Or passing model_meta.json instead of model.json or something like that.

j3nsykes commented 3 months ago

So I have tried to see if editing the array structure from how the modelTopology.configis formatted to the newer version of modelTopology.config.layers matters and is doesn't matter to https://unpkg.com/ml5@latest/dist/ml5.min.js versions (eg: it accepts both old and new array structures / old and new ways the file is saved) but neither array structure works for https://unpkg.com/ml5@0.20.0-alpha.3/dist/ml5.js which makes me think it isn't directly the array structure but more the way the model.json or model_meta.json file is loaded in load() function in the alpha versions of ML5 as you suspect.

j3nsykes commented 3 months ago

It is also unrelated to handpose.js as this error persists even on a simple mouse position regression example.