Alternative for Lambda layer in yolo3 Keras - python

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"

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);
;

Related

Keras Model Multi Input - TypeError: ('Keyword argument not understood:', 'input')

I am trying to build a CNN that receives multiple inputs and I am trying the following:
input = keras.Input()
classifier = keras.Model(inputs=input,output=classifier)
When run the code I am receiving the following error for line 6 though:
TypeError: ('Keyword argument not understood:', 'input').
A hint would be much appreciated, thank you!
Some parameters of your code are not specified. I have copied your example with some numbers that you can change back.
import keras
input_dim_1 = 10
input1 = keras.layers.Input(shape=(input_dim_1,1))
cnn_classifier_1 = keras.layers.Conv1D(64, 5, activation='sigmoid')(input1)
cnn_classifier_1 = keras.layers.Dropout(0.5)(cnn_classifier_1)
cnn_classifier_1 = keras.layers.Conv1D(48, 5, activation='sigmoid')(cnn_classifier_1)
cnn_classifier_1 = keras.models.Model(inputs=input1,outputs=cnn_classifier_1)
Some things to note
The imports of your layers were not right. You need to import the layers/models you want from the right places. You can check my code against yours to see this.
With the functional API of keras you do not need to specify the input shape as you have done in the first Conv1D layer. This is handled automatically.
You need to correctly specify the keywords in Model. Specifically inputs and outputs. Different versions of keras use input / output or inputs/outputs as keywords for the call of the class Model.
Hey, its simple, use following code:
classifier = keras.Model(input, classifier)
instead of calling
classifier = keras.Model(inputs = input, output = classifier)
Issue seems to come from latest versions of keras implementation.

How to use evaluate and predict functions in keras implementation of SincNet?

thanks for your atention, I'm developing an automatic speaker recognition system using SincNet.
Ravanelli, M., & Bengio, Y. (2018, December). Speaker recognition from raw waveform with sincnet. In 2018 IEEE Spoken Language Technology Workshop (SLT) (pp. 1021-1028). IEEE.
Since the network is coded in Pytorch I searched and found a Keras implementation here https://github.com/grausof/keras-sincnet. I adapted the train.py code to train a Sincnet with my own data in Tensorflow 2.0, and worked fine, I saved only the weights of my trained network, my training data has shape 128,3200,1 for inputs and 128 for labels per batch
#Creates a Sincnet model with input_size=3200 (wlen), num_classes=40, fs=16000
redsinc = create_model(wlen,num_classes,fs)
#Saves only weights and stopearly callback
checkpointer = ModelCheckpoint(filepath='checkpoints/SincNetBiomex3.hdf5',verbose=1,
save_best_only=True, monitor='val_accuracy',save_weights_only=True)
stopearly = EarlyStopping(monitor='val_accuracy',patience=3,verbose=1)
callbacks = [checkpointer,stopearly]
# optimizer = RMSprop(lr=learnrate, rho=0.9, epsilon=1e-8)
optimizer = Adam(learning_rate=learnrate)
# Creates generator of training batches
train_generator = batchGenerator(batch_size,train_inputs,train_labels,wlen)
validinputs, validlabels = create_batches_rnd(validation_labels.shape[0],
validation_inputs,validation_labels,wlen)
#Compiling model and train with function fit_generator
redsinc.compile(loss='sparse_categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
history = redsinc.fit_generator(train_generator, steps_per_epoch=N_batches, epochs = epochs,
verbose = 1, callbacks=callbacks, validation_data=(validinputs,validlabels))
The problem came when I tried to evaluate the network, I didn't use the code found in test.py, I only loaded the weights I previously saved and use the function evaluate, my test data had the shape 1200,3200,1 for the inputs and 1200 for labels.
# Create a Sincnet model and load previously saved weights
redsinc = create_model(wlen,num_clases,fs)
redsinc.load_weights('checkpoints/SincNetBiomex3.hdf5')
test_loss, test_accuracy = redsinc.evaluate(x=eval_in,y=eval_lab)
RuntimeError: You must compile your model before training/testing. Use `model.compile(optimizer,
loss)`.
Then I added the same compile code I used for training:
optimizer = Adam(learning_rate=0.001)
redsinc.compile(loss='sparse_categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
Then rerun the test code and got this:
WARNING:tensorflow:From C:\Users\atenc\Anaconda3\envs\py3.7-tf2.0gpu\lib\site-
packages\tensorflow_core\python\ops\resource_variable_ops.py:1781: calling
BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is
deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
ValueError: A tf.Variable created inside your tf.function has been garbage-collected. Your code needs to keep Python references to variables created inside `tf.function`s.
A common way to raise this error is to create and return a variable only referenced inside your function:
#tf.function
def f():
v = tf.Variable(1.0)
return v
v = f() # Crashes with this error message!
The reason this crashes is that #tf.function annotated function returns a **`tf.Tensor`** with the **value** of the variable when the function is called rather than the variable instance itself. As such there is no code holding a reference to the `v` created inside the function and Python garbage collects it.
The simplest way to fix this issue is to create variables outside the function and capture them:
v = tf.Variable(1.0)
#tf.function
def f():
return v
f() # <tf.Tensor: ... numpy=1.>
v.assign_add(1.)
f() # <tf.Tensor: ... numpy=2.>
I don't understand the error since I've evaluated other networks with the same function and never got any problems. Then I decided to use predict function to match predicted labels with correct labels and obtain all metrics with my own code but I got another error.
# Create a Sincnet model and load previously saved weights
redsinc = create_model(wlen,num_clases,fs)
redsinc.load_weights('checkpoints/SincNetBiomex3.hdf5')
print('Model loaded')
#Predict labels with test data
predict_labels = redsinc.predict(eval_in)
Error while reading resource variable _AnonymousVar212 from Container: localhost. This could mean that the variable was uninitialized. Not found: Resource localhost/_AnonymousVar212/class tensorflow::Var does not exist.
[[node sinc_conv1d/concat_104/ReadVariableOp (defined at \Users\atenc\Anaconda3\envs\py3.7-tf2.0gpu\lib\site-packages\tensorflow_core\python\framework\ops.py:1751) ]] [Op:__inference_keras_scratch_graph_13649]
Function call stack:
keras_scratch_graph
I hope someone can tell me what these errors mean and how to solve them, I've searched for solutions to them but most of the solutions I've found don't seem related to my problem so I can't apply those solutions. I'm guessing the errors are caused by the Sincnet layer code, because it is a custom coded layer. The code for Sincnet layer can be found in the github repository in the file sincnet.py.
I appreciate all help I can get, again thank you for your atention.
You should downgrade your tf and keras version, it works to me when I faced the same problem.
Try this keras==2.1.6; tensorflow-gpu==1.13.1

Layer not built error, even after model.build() in tensorflow 2.0.0

Reference I was following:
https://www.tensorflow.org/api_docs/python/tf/keras/Model#save
I really want to run the model; give it some inputs; grab some layer outputs coming from inside the model.
model = tf.keras.models.load_model('emb_movielens100k_all_cols_dec122019')
input_shape = (None, 10)
model.build(input_shape)
All good so far; no errors no warnings.
model.summary()
ValueError: You tried to call `count_params` on IL, but the layer isn't built. You can build it manually via: `IL.build(batch_input_shape)`
How to fix?
Following code does not fix it:
IL.build(input_shape) # no
model.layer-0.build(input_shape) # no
This seems to work: But it's a long way from my goal of running the model and grabbing some layer outputs. Isn't there an easy way in TF 2.0.0?
layer1 = model.get_layer(index=1)
This throws an error:
model = tf.saved_model.load('emb_movielens100k_all_cols_dec122019')
input_shape = (None, 10)
model.build(input_shape) #AttributeError: '_UserObject' object has no attribute 'build'
The fix was to use save_model(), not model.save(). Also needed to use save_format="h5" during save, not default format. Like this:
tf.keras.models.save_model(model, "h5_emb.hp5", save_format="h5")
Also needed to use model_load(), not saved_model.load(), to load to memory from disk. Like this:
model = tf.keras.models.load_model('h5_emb.hp5')
The other tutorial and documentation ways of doing save and load returned a model that did not work right for predictions or summary.
This is tensorflow version 2.0.0.
Hope this helps others.

Incorrect results obtained on running a model in LibTorch that was trained and exported from PyTorch

I am trying to export a trained model along with weights for inference in C++ using LibTorch. However, the output tensor results do not match.
The shape of the output tensor is the same.
model = FCN()
state_dict = torch.load('/content/gdrive/My Drive/model/trained_model.pth')
model.load_state_dict(state_dict)
example = torch.randn(1, 3, 768, 1024)
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save('/content/gdrive/My Drive/model/mymodel.pt')
However some warnings are generated which I think maybe causing the incorrect results to be generated.
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:137:
TracerWarning: Converting a tensor to a Python index might cause the
trace to be incorrect. We can't record the data flow of Python values,
so this value will be treated as a constant in the future. This means
that the trace might not generalize to other inputs!
/usr/local/lib/python3.6/dist-packages/torch/tensor.py:435:
RuntimeWarning: Iterating over a tensor might cause the trace to be
incorrect. Passing a tensor of different shape won't change the number
of iterations executed (and might lead to errors or silently give
incorrect results).'incorrect results).', category=RuntimeWarning)
Following is the LibTorch code to generate the output tensor
at::Tensor predict(std::shared_ptr<torch::jit::script::Module> model, at::Tensor &image_tensor) {
std::vector<torch::jit::IValue> inputs;
inputs.push_back(image_tensor);
at::Tensor result = model->forward(inputs).toTensor();
return result;
}
Has anyone tried using a trained PyTorch model in LibTorch?
Just ran into the same issue, and found a solution:
add
model.eval()
before
traced_script_module = torch.jit.trace(model, example)
and the model gives the same result in c++ as in python

How to get text Prediction accuracy from the saved model"

New to tensorflow, html, and stuck badly in text classification.
i'am trying to detect positive and negative polarity of text. trained the model in browser on manually filtered text (sentences) for both neagative and postive classes and saved it in .JSON and .BIN File.
async function saveFile(){ const saveResults = await model.save('downloads://my-model-1');}
Loaded back the files by user input
async function loadFile(){ const jsonUpload = document.getElementById('json-upload'); const weightsUpload = document.getElementById('weights-upload');
const model = await tf.loadModel(tf.io.browserFiles([jsonUpload.files[0], weightsUpload.files[0]]));
model.compile({loss: "categoricalCrossentropy", optimizer: "adam", metrics:'accuracy'});
model.summary();
}
summary of model loaded, trained and saved from small portion of data
stuck in Re_creating model ( ERROR: Uncaught TypeError: Sequential model cannot be built: model is empty. Add some layers first.)
What i need to do is LOAD MODEL, this model should predict the polarity of user input text as negative/positive, detection accuracy.
Any one can help please in bit detailed, As learning it but not able to get it via tutorials from https://www.tensorflow.org/js
Model
// Define a model
model = tf.sequential();
console.log(sequence_length);
//Add layers to model
model.add(tf.layers.embedding({
inputDim: vocabulary_size,
outputDim: embedding_dim,
inputLength: sequence_length,
trainable: true
}));
addCLayers();
model.add(tf.layers.dropout ({rate:0.2}));
model.add(tf.layers.flatten());
model.add(tf.layers.dense({units: 100, activation: 'sigmoid'}));
model.add(tf.layers.dense({units: 1000, activation: 'sigmoid'}));
model.add(tf.layers.dense({units: 100, activation: 'sigmoid'}));
model.add(tf.layers.dense({units: 2, activation: 'softmax'}));
I believe I see two issues.
Firstly, you're using loadModel, which has been deprecated. You'll want to switch to loadLayersModel soon. This can also accept an IOHandler, just like you're currently using.
The second thing is you need to compile the model before saving. I see you're loading and then trying to compile. There should be no need to compile after loading. You CAN however load a layerless model.
Assure your model is in good standing before you save it. That seems to be where the problem is.

Categories

Resources