Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tensorflow.js Error: Unknown layer: Functional

I'm loading a simple Tensorflow.js model using tf.loadLayersModel(), but the model is not building. I am using the Functional API to build the Model, but only consisting of Dense Layers. A similar error seems to arise with Lambda layers, but I only use 2 Dense Layers and functional layers are supported in Tf.js.

Full Error:

Error: Unknown layer: Functional. This may be due to one of the following reasons:
1. The layer is defined in Python, in which case it needs to be ported to TensorFlow.js or your JavaScript code.
2. The custom layer is defined in JavaScript, but is not registered properly with tf.serialization.registerClass()

The JS code that triggers it:

const http = tf.io.http

tf.loadLayersModel(http(url)).then((model) => {
    console.log('Loaded model.')
    console.log(model)
})

url's fetched content (aka the model.json file)

{"format": "layers-model", "generatedBy": "keras v2.4.0", "convertedBy": "TensorFlow.js Converter v2.0.1.post1", "modelTopology": {"keras_version": "2.4.0", "backend": "tensorflow", "model_config": {"class_name": "Functional", "config": {"name": "my_model", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 10], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_1"}, "name": "input_1", "inbound_nodes": []}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"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", "inbound_nodes": [[["input_1", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 20, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"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_1", "inbound_nodes": [[["dense", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 10, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"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_2", "inbound_nodes": [[["dense_1", 0, 0, {}]]]}], "input_layers": [["input_1", 0, 0]], "output_layers": [["dense_2", 0, 0]]}}, "training_config": {"loss": "mse", "metrics": "accuracy", "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "RMSprop", "config": {"name": "RMSprop", "learning_rate": 0.001, "decay": 0.0, "rho": 0.9, "momentum": 0.0, "epsilon": 1e-07, "centered": false}}}}, "weightsManifest": [{"paths": ["group1-shard1of1.bin"], "weights": [{"name": "dense/kernel", "shape": [10, 20], "dtype": "float32"}, {"name": "dense/bias", "shape": [20], "dtype": "float32"}, {"name": "dense_1/kernel", "shape": [20, 20], "dtype": "float32"}, {"name": "dense_1/bias", "shape": [20], "dtype": "float32"}, {"name": "dense_2/kernel", "shape": [20, 10], "dtype": "float32"}, {"name": "dense_2/bias", "shape": [10], "dtype": "float32"}]}]}

Want to reproduce the model? Here's the python code:

import keras
import keras.layers as layers
import tensorflowjs as tfjs

inputs = keras.Input(shape=(10,))
dense = layers.Dense(20, activation="relu")
x = dense(inputs)
x = layers.Dense(20, activation="relu")(x)
outputs = layers.Dense(10)(x)

# Create the model
model = keras.Model(inputs=inputs, outputs=outputs, name="my_model")

KEY = 'sampleid'
MDL = 'mymodel'

model.compile(loss='mse',metrics='accuracy')

tfjs.converters.save_keras_model(model, MDL)

NOTE: The URL is a bit verbose (it's a Firebase Storage downloadURL) and I'm not confident the IOHandler (http) can parse the weightPathPrefix perfectly. I am not sure this is the issue or even an issue, but it could create problems if it was incorrect and I don't know how to check it's calculated value.

Versions:

JS:  Tensorflow.js : 2.0.1
Py:  Tensorflowjs  : 2.0.1.post1
Py:  Keras         : 2.4.3

Update 7/29/20:

The issue seems to be in the parsing of the model weights (see NOTE). I added this example to a GitHub ticket about the tf.loadLayersModel() function earlier, which contains a lot of details about attempted solutions.

like image 560
Ryan Cocuzzo Avatar asked Dec 04 '25 04:12

Ryan Cocuzzo


1 Answers

Python tensorflow uses Functional as a class name of functional models, but tfjs use a different name for them internally.

Try changing modelTopology.model_config.class_name in model.json to Model.

like image 160
Remagpie Avatar answered Dec 07 '25 17:12

Remagpie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!