Save caffe model after deleting layers from it - python

I have a caffe model with me which has crop layers in it so converting it to TensorFlow is posing a problem.
I have successfully loaded the model and dropped the crop layers and now I would like to save the corresponding model.prototxt and model.caffemodel
I found the following questions on StackOverflow but they are about replacing the layers and not permanently deleting them:
Layer drop and update caffe model
How to modify the Imagenet Caffe Model?
When I save the model using caffe.Net.save() only the model.caffemodel file gets saved and not the corresponding .prototxt. What to do ?
Model files : https://github.com/Charrin/RetinaFace-Cpp/tree/master/convert_models/mnet
Code used so far -
import caffe
net = caffe.Net('mnet.prototxt', 'mnet.caffemodel' , caffe.TEST)
del net.layer_dict['crop1']
del net.layer_dict['crop0']
net.save('new_model.caffemodel')

Related

How to convert a pretrained tensorflow pb frozen graph into a modifiable h5 keras model?

I have been searching for a method to do this for so long, and I can not find an answer. Most threads I found are of people wanting to do the opposite.
Backstory:
I am experimenting with some pre-trained models provided by the tensorflow/models repository. The models are saved as .pb frozen graphs. I want to fine-tune some of these models by changing the final layers to suit my application.
Hence, I want to load the models inside a jupyter notebook as a normal keras h5 model.
How can I do that?
do you have a better way to do so?
Thanks.
seems like all you would have to do is download the model files and store them in a directory. Call the directory for example c:\models. Then load the model.
model = tf.keras.models.load_model(r'c:\models')
model.summary() # prints out the model layers
# generate code to modify the model as you typically do for transfer learning
# compile the changed model
# train the model
# save the trained model as a .h5 file
dir=r'path to the directory you want to save the model to'
model_identifier= 'abcd.h5' # for abcd use whatever identification you want
save_path=os.path.join(dir, model_identifier)
model.save(save_path)

How to load the weights of the first few layers of Convolutional Neural Network in Keras and delete the pre-trained model?

I have a pretrained model trained in Keras.
I am trying to use that model in another task, but I don't need all the layers, but only the first 4 conv layers.
I have the model saved in "keras_pretrained_model.h5"
Is it possible to initialize the first 4 conv layers of the new model using the weights of the first 4 conv layers of the pretrained model from the '.h5' file?
Is loading the whole pretrained model first always necessary??
The pretrained model actually takes up a lot of space and I am not sure how to delete the pretrained model after I initializing the new model with the weights. As far as I understand, using tf.keras.backend.clear_session() will clear the new model created along with the old one.
So, my question is
Is there any way to initialize the weights in the new model layers without loading the whole pretrained model?
If I have to load the whole pretrained model, how to delete only the pretrained model without harming the new model in any way?
I have thought of two processes
If the names of the layers of the first 4 layers of the new model is same as the 4 layers in the pre-trained model, then
new_model.load_weights(path_to_old_model_file, by_name = True)
If the names don't mathc, then we can do layer wise weight initialization by taking the weights from the corresponding layers in the old model h5 file and setting the weights using set_weights() method.
I have written a code, which I have uploaded to github, here.
I would be very grateful, if anyone seeing this gives a feedback on this!!

get Embeddings by reloading tensorflow model

I saved a tensorflow model, .pb file, trained using transfer learning taking this as reference with following code added at the end:
tf.train.write_graph(graph_name, saving_dir_path, output.pb, as_text=False)
and it successfully saved. But now after training I want to get Embedding's output. Following is the last layer defined to train in the graph under layer name final_training_ops:
with tf.name_scope('Wx_plus_b'):
logits = tf.add(tf.matmul(bottleneck_input, layer_weights), layer_biases, name='logits')
After reloading saved model I am using tf.get_default_graph().get_tensor_by_name('Wx_plus_b/logits') to access layer so as to pass image to get embeddings but getting error as invalid operation name.
I gave more time to it and found correct syntax is of the form <op_name>:<output_index> -
tf.get_default_graph().get_tensor_by_name('Wx_plus_b/logits:0')

I use TFLiteConvert post_training_quantize=True but my model is still too big for being hosted in Firebase ML Kit's Custom servers

I have written a TensorFlow / Keras Super-Resolution GAN. I've converted the resulting trained .h5 model to a .tflite model, using the below code, executed in Google Colab:
import tensorflow as tf
model = tf.keras.models.load_model('/content/drive/My Drive/srgan/output/srgan.h5')
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.post_training_quantize=True
tflite_model = converter.convert()
open("/content/drive/My Drive/srgan/output/converted_model_quantized.tflite", "wb").write(tflite_model)
As you can see I use converter.post_training_quantize=True which was censed to help to output a lighter .tflite model than the size of my original .h5 model, which is 159MB. The resulting .tflite model is still 159MB however.
It's so big that I can't upload it to Google Firebase Machine Learning Kit's servers in the Google Firebase Console.
How could I either:
decrease the size of the current .tflite model which is 159MB (for example using a tool),
or after having deleted the current .tflite model which is 159MB, convert the .h5 model to a lighter .tflite model (for example using a tool)?
Related questions
How to decrease size of .tflite which I converted from keras: no answer, but a comment telling to use converter.post_training_quantize=True. However, as I explained it, this solution doesn't seem to work in my case.
In general, quantization means, shifting from dtype float32 to uint8. So theoretically our model should reduce by the size of 4. This will be clearly visible in files of greater size.
Check whether your model has been quantized or not by using the tool "https://lutzroeder.github.io/netron/". Here you have to load the model and check the random layers having weight.The quantized graph contains the weights value in uint8 format
In unquantized graph the weights value will be in float32 format.
Only setting "converter.post_training_quantize=True" is not enough to quantize your model. The other settings include:
converter.inference_type=tf.uint8
converter.default_ranges_stats=[min_value,max_value]
converter.quantized_input_stats={"name_of_the_input_layer_for_your_model":[mean,std]}
Hoping you are dealing with images.
min_value=0, max_value=255, mean=128(subjective) and std=128(subjective). name_of_the_input_layer_for_your_model= first name of the graph when you load your model in the above mentioned link or you can get the name of the input layer through the code "model.input" will give the output "tf.Tensor 'input_1:0' shape=(?, 224, 224, 3) dtype=float32". Here the input_1 is the name of the input layer(NOTE: model must include the graph configuration and the weight.)

Can't convert Keras model to tflite

I have a Keras model saved with the following line:
tf.keras.models.save_model(model, "path/to/model.h5")
Later, I try to convert it to a tflite file as follows:
converter = tf.contrib.lite.TFLiteConverter.from_keras_model_file('path/to/model.h5')
tflite_model = converter.convert()
open("path/to/model.tflite", "wb").write(tflite_model)
But I get a weird error:
You are trying to load a weight file containing 35 layers into a model with 0 layers.
I know that my model is working fine. I am able to load it and draw inferences. This error only shows up when trying to save it as a tflite model.
TensorFlow version: tensorflow-gpu 1.12.0
I'm using tf.keras.
Turns out, the issue is due to explicitly defining an InputLayer with some input_shape.
My model was of the form:
InputLayer(input_shape=(...))
BatchNormalization()
.... Remaining layers
I changed it to:
BatchNormalization(input_shape=(...))
.... Remaining layers
and transferred the weights from the previous model here. Now it works perfectly.

Categories

Resources