How to not re-initialize the pretrained loaded model in Tensorflow? - python

I have loaded a pretrained model (Model 1) using the following code:
def load_seq2seq_model(sess):
with open(os.path.join(seq2seq_config_dir_path, 'config.pkl'), 'rb') as f:
saved_args = pickle.load(f)
# Initialize the model with saved args
model = Model1(saved_args)
#Inititalize Tensorflow saver
saver = tf.train.Saver()
# Checkpoint
ckpt = tf.train.get_checkpoint_state(seq2seq_config_dir_path)
print('Loading model: ', ckpt.model_checkpoint_path)
# Restore the model at the checkpoint
saver.restore(sess, ckpt.model_checkpoint_path)
return model
Now, I want to train another model (Model 2) from scratch which will take the output of the Model 1. But for that I need to define a session and load the pre-trained model and initialize the model tf.initialize_all_variables(). So, the pre-trained model will also get initialized.
Can anyone please tell me how to train the Model 2 after getting the output from the pre-trained model Model 1 properly?
What I am trying is given below -
with tf.Session() as sess:
# Initialize all the variables of the graph
seq2seq_model = load_seq2seq_model(sess)
sess.run(tf.initialize_all_variables())
.... Rest of the training code goes here....

All variables that are restored using a saver don't need to be initialized. Therefore, instead of using tf.initialize_all_variables() you can use tf.variables_initializer(var_list) to only initialize the weights of the second network.
To get a list of all the weights of the second network you can create the Model 2 network in a variable scope:
with tf.variable_scope("model2"):
model2 = Model2(...)
Then use
model_2_variables_list = tf.get_collection(
tf.GraphKeys.GLOBAL_VARIABLES,
scope="model2"
)
to get the variable list of the Model 2 network. Finally you can create the initialisier for the second network:
init2 = tf.variables_initializer(model_2_variables_list)
with tf.Session() as sess:
# Initialize all the variables of the graph
seq2seq_model = load_seq2seq_model(sess)
sess.run(init2)
.... Rest of the training code goes here....

Related

Correct way to upload weights at inference for faster-rcnn model?

I was wondering what is the correct way of uploading saved weights for a trained model at inference.
As an FYI, I train my model using pretrained coco weights and pretrained imagenet weights:
model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True, pretrained_backbone=True)
num_classes = 2
# get number of input features for the classifier
in_features = model.roi_heads.box_predictor.cls_score.in_features
# replace the pre-trained head with a new one
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
model.to(device)
I then save the model dict in a dictionary where the state is saved like:
'state_dict': model.state_dict()
Once trained, I upload the weights like:
# set up model
model_test = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True, pretrained_backbone=True)
num_classes = 2
# get number of input features for the classifier
in_features = model_test.roi_heads.box_predictor.cls_score.in_features
# replace the pre-trained head with a new one
model_test.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
model_test.to(device)
bestmodel = get_best_model(args.best)
bestmodel = torch.load(bestmodel)
model_test.load_state_dict(bestmodel['state_dict'])
As you can see, I also upload the pretrained weights at inference (test time). However, you can see that I then upload the weights from my saved model (bestmodel).
I thought by uploading weights, that this would override the initial pretrained weights uploaded. However, when I set the test model to :
model_test = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False, pretrained_backbone= False)
And continue to upload my best model, I get slightly worse performance (marginally).
Is there a correct way to upload these weights? And if it shouldn't matter, why do I get a difference?

Tensorflow: how to use pretrained weights in new graph?

I'm trying to build an object detector with CNN using tensorflow with python framework. I would like to train my model to do just object recognition (classification) at first and then using several convolutional layers of the pretarined model train it to predict bounding boxes. I will need to replace fully connected layers and probably some last convolutional layers. So, for this reason, I would like to know if it is possible to import only weights from tensorflow graph that was used to train object classifier to a newly defined graph that I will train to do object detection. So basically I would like to do something like this:
# here I initialize the new graph
conv_1=tf.nn.conv2d(in, weights_from_old_graph)
conv_2=tf.nn.conv2d(conv_1, weights_from_old_graph)
...
conv_n=tf.nn.nnconv2d(conv_n-1,randomly_initialized_weights)
fc_1=tf.matmul(conv_n, randomly_initalized_weights)
Use saver with no arguments to save the entire model.
tf.reset_default_graph()
v1 = tf.get_variable("v1", [3], initializer = tf.initializers.random_normal)
v2 = tf.get_variable("v2", [5], initializer = tf.initializers.random_normal)
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
saver.save(sess, save_path='./test-case.ckpt')
print(v1.eval())
print(v2.eval())
saver = None
v1 = [ 2.1882825 1.159807 -0.26564872]
v2 = [0.11437789 0.5742971 ]
Then in the model you want to restore to certain values, pass a list of variable names you want to restore or a dictionary of {"variable name": variable} to the Saver.
tf.reset_default_graph()
b1 = tf.get_variable("b1", [3], initializer= tf.initializers.random_normal)
b2 = tf.get_variable("b2", [3], initializer= tf.initializers.random_normal)
saver = tf.train.Saver(var_list={'v1': b1})
with tf.Session() as sess:
saver.restore(sess, "./test-case.ckpt")
print(b1.eval())
print(b2.eval())
INFO:tensorflow:Restoring parameters from ./test-case.ckpt
b1 = [ 2.1882825 1.159807 -0.26564872]
b2 = FailedPreconditionError: Attempting to use uninitialized value b2
Although I agree with Aechlys to restore variables. The problem is harder when we want to fix these variables. For example, we trained these variables and we want to use them in another model, but this time without training them (training new variables like in transfer-learning). You can see the answer I posted here.
Quick example:
with tf.session() as sess:
new_saver = tf.train.import_meta_graph(pathToMeta)
new_saver.restore(sess, pathToNonMeta)
weight1 = sess.run(sess.graph.get_tensor_by_name("w1:0"))
tf.reset_default_graph() #this will eliminate the variables we restored
with tf.session() as sess:
weights =
{
'1': tf.Variable(weight1 , name='w1-bis', trainable=False)
}
...
We are now sure the restored variables are not a part of the graph.

How to extract features from the last layer of slim-tensorflow InceptionNet v3 model?

I fine-tuned InceptionNet v3 model given in the slim-tensorflow library. I trained the model on my own dataset. Now, I have .ckpt and .meta file for the model.
Now, as far as from I understand, I have two ways to restore the model and the weights. First, from the .meta file like this
checkpoint = './fine_tuned_model/model.ckpt-233700.meta'
with tf.Session() as sess:
new_saver = tf.train.import_meta_graph(checkpoint)
print(new_saver)
new_saver.restore(sess, tf.train.latest_checkpoint('./fine_tuned_model/'))
The second way is to call the model and restore the checkpoint. Like this
with slim.arg_scope(slim.nets.inception.inception_v3_arg_scope()):
logits, inceptionv3 = nets.inception.inception_v3(inputs=img, num_classes=5980, is_training=True,
dropout_keep_prob=.6)
# Restore convolutional layers:
variables_to_restore = slim.get_variables_to_restore(exclude=['InceptionV3/Logits', 'InceptionV3/AuxLogits'])
init_fn = slim.assign_from_checkpoint_fn(model_path, variables_to_restore)
Now, I think for my purpose second way is easier.
Now, my issue is that after restoring the model, how can I extract features from the last to last layer given an Image? I have included a screenshot of the model here
One solution I found was like this and here as far as I know I have to extract features from PreLogits layer but I am not sure how to set the values here
with tf.Session() as sess:
feature_tensor = sess.graph.get_tensor_by_name('mul:0')
features_last_layer = sess.run(feature_tensor,{inputs: img})
print features_last_layer
Here, I am unable to find out what should I pass to get_tenor_by_name(??) and also, how pass sess.run here?
Thank you. Please let me know if there are other ways to restore the model and get the features.
I have figured out the solution for this.
# Placeholder for the image,
image_tensor = tf.placeholder(tf.float32, shape=(None, 128, 128, 3))
# load the model
with slim.arg_scope(slim.nets.inception.inception_v3_arg_scope()):
logits, inceptionv3 = nets.inception.inception_v3(image_tensor,is_training=False)
# Restore convolutional layers:
variables_to_restore = slim.get_variables_to_restore(exclude=['InceptionV3/Logits', 'InceptionV3/AuxLogits'])
# get the latest checkpoint you want to use after training
init_fn = slim.assign_from_checkpoint_fn(model_path, variables_to_restore)
checkpoint = './fine_tuned_model/model.ckpt-233700.data-00000-of-00001'
saver = tf.train.Saver(variables_to_restore)
saver.restore(sess, tf.train.latest_checkpoint('./fine_tuned_model/'))
# the required image
img_car = cv2.imread('car.jpeg')
img_car = cv2.resize(img_car,(128, 128))
imgnumpy = np.ndarray((1,128,128,3))
imgnumpy[0] = img_car
# get output from any layer you want.
output = sess.run(inceptionv3["PreLogits"], feed_dict={image_tensor: imgnumpy})

Extract Embedding from GCMLE Saved Model

I am trying to download embeddings from a trained GCMLE prediction model locally so that I can play with my own custom embedding visualizations that aren't available in tensorboard. I'd like to extract these embeddings into a largy numpy matrix, but I'm having trouble with a few steps. I can successfully download all of the files (saved_model.pb + assets/* + variables/*, and I appear to be able to restore the model with the following code:
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess,[tf.saved_model.tag_constants.SERVING], _EXPORT_DIR)
which successfully returns:
INFO:tensorflow:Restoring parameters from Servo/variables/variables
I then tried to extract the weights like this:
constant_values = {}
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], _EXPORT_DIR)
constant_ops = [op for op in sess.graph.get_operations() if op.type == "Const"]
for constant_op in constant_ops:
constant_values[constant_op.name] = sess.run(constant_op.outputs[0])
which did succesfully output quite a lot, but the only parts relevant to the embedding were:
u'embedding_layer/embeddings/Initializer/random_uniform/max': 0.012765553,
u'embedding_layer/embeddings/Initializer/random_uniform/min': -0.012765553,
u'embedding_layer/embeddings/Initializer/random_uniform/shape': array([vocab_size, word_embedding_size], dtype=int32)
and no sign of the actual embedding weights. How can I modify my approach above to get the actual embedding weight matrix?
It will depend a bit on how you exported model, but in most cases, the embeddings are Variables and not constants. So you want something like:
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], _EXPORT_DIR)
trainable_coll = sess.graph.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)
vars = {v.name:sess.run(v.value()) for v in trainable_coll}

Tensorflow: How to use a trained model in a application?

I have trained a Tensorflow Model, and now I want to export the "function" to use it in my python program. Is that possible, and if yes, how? Any help would be nice, could not find much in the documentation. (I dont want to save a session!)
I have now stored the session as you suggested. I am loading it now like this:
f = open('batches/batch_9.pkl', 'rb')
input = pickle.load(f)
f.close()
sess = tf.Session()
saver = tf.train.Saver()
saver.restore(sess, 'trained_network.ckpt')
y_pred = []
sess.run(y_pred, feed_dict={x: input})
print(y_pred)
However, I get the error "no Variables to save" when I try to initialize the saver.
What I want to do is this: I am writing a bot for a board game, and the input is the situation on the board formatted into a tensor. Now I want to return a tensor which gives me the best position to play next, i.e. a tensor with 0 everywhere and a 1 at one position.
I don't know if there is any other way to do it, but you can use your model in another Python program by saving your session:
Your training code:
# build your model
sess = tf.Session()
# train your model
saver = tf.train.Saver()
saver.save(sess, 'model/model.ckpt')
In your application:
# build your model (same as training)
sess = tf.Session()
saver = tf.train.Saver()
saver.restore(sess, 'model/model.ckpt')
You can then evaluate any tensor in your model using a feed_dict. This obviously depends on your model. For example:
#evaluate tensor
sess.run(y_pred, feed_dict={x: input_data})

Categories