Keras: 2.3.1
Tensorflow: 2.20
Tensorflow.js: 1.7.2
tfjs-react-native: ^0.2.3
expo: ~37.0.3
react: ^16.9.0
I'm trying to run a tfjs model in react native, but when I run it, I get
Error: layer: improper config format
and then what seems to be the entirety of my model.json starting from input. The SavedModel loads into python fine, but the error occurs after conversion.
One thing to note is that my SavedModel uses a custom loss function, so whilst loading it in I have to pass it in as a custom object.
Link to model(h5): https://www.dropbox.com/s/6ginejkhna1sic8/unet_70.h5?dl=0
Link to model(Saved): https://www.dropbox.com/s/5pmogdeuwehblbz/saved-model.zip?dl=0
Link to Tensorflowjs Model: https://www.dropbox.com/s/1aewj9j4r489fcu/tfjs_model2.zip?dl=0
Command used to convert the SavedModel to tfjs:
tensorflowjs_converter --input_format=tf_saved_model --output_format=tfjs_graph_model --quantization_bytes=1 --weight_shard_size_bytes=9999999999999 ~/PycharmProjects/TrueSky/models/saved-model ~/PycharmProjects/TrueSky/models/tfjs_model2
Code used to convert h5 file to SavedModel:
import segmentation_models as sm
from keras import backend as K
from tensorflow.keras.models import load_model
from keras import layers
import tensorflow.keras.layers as KL
import tensorflow.keras.activations as tfa
from tensorflow import keras
import tensorflow as tf
def swish(x):
return (K.sigmoid(x) * x)
path_to_model = "models/unet_70.h5"
loss = sm.losses.binary_focal_dice_loss
model = load_model(path_to_model, custom_objects={'binary_focal_loss_plus_dice_loss': loss, 'FixedDropout': KL.Dropout, 'swish': swish})
model.save('models/saved-model')
Code used to test model in tfjs:
import React, { Component } from 'react';
import { Camera } from 'expo-camera';
import { cameraWithTensors, fetch, decodeJpeg, bundleResourceIO } from '@tensorflow/tfjs-react-native';
import { View, Text, StyleSheet, Platform } from 'react-native'
import * as Permissions from 'expo-permissions';
import { CameraStyle } from './styles'
import * as tf from '@tensorflow/tfjs';
import { any } from '@tensorflow/tfjs';
//import Swish from '/Users/alex/Documents/GitHub/TrueSkyApp/src/components/swish.js'
class Swish extends tf.layers.Layer {
constructor(config) {
super(config);
this.alpha = config.alpha;
}
call(input) {
return tf.tidy(() => {
const x = input[0]; //tf.getExactlyOneTensor(input);
return tf.sigmoid(x.mul(this.alpha)).mul(x);
});
}
computeOutputShape(inputShape){
return inputShape;
}
static get className() {
return 'swish';
}
}
tf.serialization.registerClass(Swish)
class FixedDropout extends tf.layers.Layer {
constructor(config) {
super(config);
this.alpha = config.alpha;
}
call(input) {
return input;
}
computeOutputShape(inputShape){
return inputShape;
}
static get className() {
return 'FixedDropout';
}
}
tf.serialization.registerClass(FixedDropout)
const modelJson = require('/Users/alex/Documents/GitHub/TrueSkyApp/assets/model/model.json');
const modelWeights = require('/Users/alex/Documents/GitHub/TrueSkyApp/assets/model/group1-shard1of1.bin');
class TFtest extends Component {
state = {
isModelReady: false
}
async componentDidMount() {
await tf.ready()
this.model = await tf.loadLayersModel(bundleResourceIO(modelJson, modelWeights));
this.setState({
isModelReady: true
})
//Output in Expo console
console.log(this.state.isModelReady)
const inputTensor = tf.randomNormal([1,320,320,3])
const prediction = await this.model.predict(inputTensor)
console.log(prediction)
}
render() {
return (
<View style={styles.container}>
<Text>Model ready? {this.state.isModelReady ? <Text>Yes</Text> : ''}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
})
export default TFtest;
Just realised I was doing LoadLayersModel instead of LoadGraphModel
Most helpful comment
Just realised I was doing LoadLayersModel instead of LoadGraphModel