问题
My Goal
I want to train a custom object detection model in Tensorflow(python) and use it using Tensorflow js after digging lot of example I found this which is widely popular
What I have done
I have written ( taken help form online examples ) the Tensorflow JS part to load a model from local and get the get the predictions. I used with COCO pretrained model It is working fine (so not adding the code here).
What is my problem
I am very new to python and Tensorflow. The example for training qqwweee/keras-yolo3 the model is in python and it is Lamda from Keras
from keras.layers import Input, Lambda
for this places
model.compile(optimizer=Adam(lr=1e-3), loss={
# use custom yolo_loss Lambda layer.
'yolo_loss': lambda y_true, y_pred: y_pred})
And
model.compile(optimizer=Adam(lr=1e-4), loss={'yolo_loss': lambda y_true, y_pred: y_pred}) # recompile to apply the change
And
model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',
arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})(
[*model_body.output, *y_true])
model = Model([model_body.input, *y_true], model_loss)
So What I understood so far, Lambda is mainly used for calculating the loss function, and this is causing main problem in TFJS because Lambda layer is not implemented till now I want to use some alternative instead of lambda layer. This is the error I am getting while using the trained model in TFJS
Error loading layer ValueError: Unknown layer: Lambda. 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().
Similar question is also asked here "Unknown layer: Lambda" in tensorflowjs on browser, it talks about writing a custom layer , the example is not enough to do that, ultimately leads to dead end.
What I want
- Is there any way to use any other loss function insteed of lambda ? how?
- Is there any example for writing custom layer for lambda
- Where are my understanding are wrong?
p.s: I spent hell lot of time to find the solution, any help will be appreciated, Thanks in advance
After adding the empty lambda layer given by @edkeveked (Thanks!), the error Error loading layer ValueError: Unknown layer: Lambda
is gone but ran into something else.
Check the model summary here
Now, In the model warmup itslef thorowing this error code for warmup
let zero = tfNode.zeros([1, 416, 416, 3]);
const result = await this.model.predict(zero)
result.map(async (t) => await t.data());
result.map(async (t) => t.dispose());
code for image prediction
batched = tfNode.tidy(() => {
if (!(img instanceof tfNode.Tensor)) {
img = tfNode.browser.fromPixels(img);
}
return img.expandDims(0);
});
result = await this.model.predict(batched);
Error I am getting
"Error: Error when checking model : the Array of Tensors that you are passing to your model is not the size the the model expected. Expected to see 4 Tensor(s), but instead got 1 Tensors(s).
at new ValueError (XXX\node_modules\@tensorflow\tfjs-layers\dist\errors.js:68:28)
at checkInputData (XXX\node_modules\@tensorflow\tfjs-layers\dist\engine\training.js:316:19)
at LayersModel.predict (XXX\node_modules\@tensorflow\tfjs-layers\dist\engine\training.js:981:9)
at ObjectDetection.warmUp (XXX\tensorflow_predownloaded_model.js:47:45)
at XXX\tensorflow_predownloaded_model.js:38:18"
回答1:
Since the Lambda layer is not yet supported, it need to be provided for the conversion to work. Moreover, the loaded layer is not used for training, so the lambda layer can be empty. (code not tried)
class Lambda extends tf.layers.Layer {
constructor() {
super({})
}
static get className() {
return 'Lambda';
}
}
tf.serialization.SerializationMap.register(Lambda);
;
来源:https://stackoverflow.com/questions/59233377/alternative-for-lambda-layer-in-yolo3-keras