teachablemachine-community
teachablemachine-community copied to clipboard
[BUG]: Teachable Machine model.json file not compatible with Tenserflow/Keras Expectations
Describe the bug
To Reproduce Steps to reproduce the behavior:
-
download model.json file from a teachable machine model
-
read it in as a string in python with the following code:
with open(modelPath) as f: lines=f.readLines() modelJson = ''.join(lines) model = models.model_from_json(modelJson)
-
Run the program, receive a
ValueError: Improper config format
error
Reason for Bug
This occurs because the JSON given by teachable machine is not in the same format as that expected by TF. Tensorflow expects the following format (created by saving a tf model saved as a .h5 as a JSON):
{ "class_name": "Sequential", "config": { "name": "sequential", "layers": [ { "class_name": "InputLayer", "config": { "batch_input_shape": [ null, 256, 256, 1 ], "dtype": "float32", "sparse": false, "ragged": false, "name": "rescaling_input" } }, { "class_name": "Rescaling", "config": { "name": "rescaling", "trainable": true, "dtype": "float32", "scale": 0.00392156862745098, "offset": 0 } }, { "class_name": "Conv2D", "config": { "name": "conv2d", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": [ 3, 3 ], "strides": [ 1, 1 ], "padding": "valid", "data_format": "channels_last", "dilation_rate": [ 1, 1 ], "groups": 1, "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 } }, { "class_name": "MaxPooling2D", "config": { "name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": [ 2, 2 ], "padding": "valid", "strides": [ 2, 2 ], "data_format": "channels_last" } }, { "class_name": "Conv2D", "config": { "name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": [ 3, 3 ], "strides": [ 1, 1 ], "padding": "valid", "data_format": "channels_last", "dilation_rate": [ 1, 1 ], "groups": 1, "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 } }, { "class_name": "MaxPooling2D", "config": { "name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": [ 2, 2 ], "padding": "valid", "strides": [ 2, 2 ], "data_format": "channels_last" } }, { "class_name": "Conv2D", "config": { "name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": [ 3, 3 ], "strides": [ 1, 1 ], "padding": "valid", "data_format": "channels_last", "dilation_rate": [ 1, 1 ], "groups": 1, "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 } }, { "class_name": "MaxPooling2D", "config": { "name": "max_pooling2d_2", "trainable": true, "dtype": "float32", "pool_size": [ 2, 2 ], "padding": "valid", "strides": [ 2, 2 ], "data_format": "channels_last" } }, { "class_name": "Flatten", "config": { "name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last" } }, { "class_name": "Dense", "config": { "name": "dense", "trainable": true, "dtype": "float32", "units": 128, "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 } }, { "class_name": "Dense", "config": { "name": "dense_1", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "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 } } ] }, "keras_version": "2.6.0", "backend": "tensorflow" }
However, teachable machine has the following format, seen here:
{ "modelTopology": { "class_name": "Sequential", "config": { "name": "sequential_2", "layers": [ { "class_name": "Dense", "config": { "units": 100, "activation": "relu", "use_bias": true, "kernel_initializer": { "class_name": "VarianceScaling", "config": { "scale": 1, "mode": "fan_in", "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, 14739 ], "dtype": "float32" } }, { "class_name": "Dropout", "config": { "rate": 0.5, "noise_shape": null, "seed": null, "name": "dropout_Dropout1", "trainable": true } }, { "class_name": "Dense", "config": { "units": 4, "activation": "softmax", "use_bias": false, "kernel_initializer": { "class_name": "VarianceScaling", "config": { "scale": 1, "mode": "fan_in", "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.3.1", "backend": "tensor_flow.js" }, "format": "layers-model", "generatedBy": "TensorFlow.js tfjs-layers v1.3.1", "convertedBy": null, "weightsManifest": [ { "paths": [ "./model.weights.bin" ], "weights": [ { "name": "dense_Dense1/kernel", "shape": [ 14739, 100 ], "dtype": "float32" }, { "name": "dense_Dense1/bias", "shape": [ 100 ], "dtype": "float32" }, { "name": "dense_Dense2/kernel", "shape": [ 100, 4 ], "dtype": "float32" } ] } ] }
The modelTopology
section and the data at the bottom is unecessary.
Work Around
We found a work around by simply pruning the model.json
file given by TM to the format given in the first example. However, our team believes this to be a problem that should be fixed.
Desktop (please complete the following information):
- OS: Ubuntu 20.04
I'm having the same issue. How do I get the weights in a h5 format?