Unable to locate input tensor in tf.graph (saved_model)

Viewed 428

After training, I saved my model to saved_model format (I want to save it to this format not .h5). When loading the model and printing the graph, I can't find the input tensor (only serving_default_input). to be able to make a prediction.

First time, I defined my model using keras.applications.VGG16 and then added keras.Input() but nothing changed.

this is how I defined my model :

model = keras.applications.VGG16(weights = "imagenet",
                     include_top = False,
                     input_shape = (IMG_SIZE[0],IMG_SIZE[1], 3))
for layer in model.layers:
    layer.trainable = False

x = model.output
x = Dense(16 , activation="relu")(x)
x = Flatten()(x)
predictions = Dense(1, activation = "sigmoid")(x)
model = Model(inputs = model.input, outputs = predictions)
model.summary()  #in the first attempt :

Model: "model_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_3 (InputLayer)         [(None, 512, 512, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 512, 512, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 512, 512, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 256, 256, 64)      0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 256, 256, 128)     73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 256, 256, 128)     147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 128, 128, 128)     0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 128, 128, 256)     295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 128, 128, 256)     590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 128, 128, 256)     590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 64, 64, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 64, 64, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 64, 64, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 64, 64, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 32, 32, 512)       0         
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 32, 32, 512)       2359808   
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 16, 16, 512)       0         
_________________________________________________________________
dense_5 (Dense)              (None, 16, 16, 16)        8208      
_________________________________________________________________
flatten_3 (Flatten)          (None, 4096)              0         
_________________________________________________________________
dense_6 (Dense)              (None, 1)                 4097      
=================================================================
Total params: 14,726,993
Trainable params: 12,305
Non-trainable params: 14,714,688
_________________________________________________________________
None

model.summary()  #in the second attempt :

Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_5 (InputLayer)         [(None, 512, 512, 3)]     0         
_________________________________________________________________
vgg16 (Model)                (None, 16, 16, 512)       14714688  
_________________________________________________________________
dense_3 (Dense)              (None, 16, 16, 16)        8208      
_________________________________________________________________
flatten_2 (Flatten)          (None, 4096)              0         
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 4097      
=================================================================
Total params: 14,726,993
Trainable params: 12,305
Non-trainable params: 14,714,688
_________________________________________________________________
None

from keras point of view. After conversion to SavedModel,

tf.reset_default_graph()
graph = tf.Graph()
sess =  tf.Session(graph=graph) 
tf.saved_model.loader.load(sess, [tf.saved_model.SERVING], "SavedModel")
sess.graph.get_operations()
[<tf.Operation 'dense_3_1/kernel' type=VarHandleOp>,
 <tf.Operation 'dense_3_1/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
<tf.Operation 'dense_3_1/bias' type=VarHandleOp>,
 <tf.Operation 'dense_3_1/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'dense_4_1/kernel' type=VarHandleOp>,
 <tf.Operation 'dense_4_1/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'dense_4_1/bias' type=VarHandleOp>,
 <tf.Operation 'dense_4_1/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block1_conv1/kernel' type=VarHandleOp>,
 <tf.Operation 'block1_conv1/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block1_conv1/bias' type=VarHandleOp>,
 <tf.Operation 'block1_conv1/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block1_conv2/kernel' type=VarHandleOp>,
 <tf.Operation 'block1_conv2/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block1_conv2/bias' type=VarHandleOp>,
 <tf.Operation 'block1_conv2/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block2_conv1/kernel' type=VarHandleOp>,
 <tf.Operation 'block2_conv1/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block2_conv1/bias' type=VarHandleOp>,
 <tf.Operation 'block2_conv1/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block2_conv2/kernel' type=VarHandleOp>,
 <tf.Operation 'block2_conv2/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block2_conv2/bias' type=VarHandleOp>,
 <tf.Operation 'block2_conv2/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block3_conv1/kernel' type=VarHandleOp>,
 <tf.Operation 'block3_conv1/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block3_conv1/bias' type=VarHandleOp>,
 <tf.Operation 'block3_conv1/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block3_conv2/kernel' type=VarHandleOp>,
 <tf.Operation 'block3_conv2/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block3_conv2/bias' type=VarHandleOp>,
 <tf.Operation 'block3_conv2/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block3_conv3/kernel' type=VarHandleOp>,
 <tf.Operation 'block3_conv3/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block3_conv3/bias' type=VarHandleOp>,
 <tf.Operation 'block3_conv3/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block4_conv1/kernel' type=VarHandleOp>,
 <tf.Operation 'block4_conv1/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block4_conv1/bias' type=VarHandleOp>,
 <tf.Operation 'block4_conv1/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block4_conv2/kernel' type=VarHandleOp>,
 <tf.Operation 'block4_conv2/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block4_conv2/bias' type=VarHandleOp>,
 <tf.Operation 'block4_conv2/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block4_conv3/kernel' type=VarHandleOp>,
 <tf.Operation 'block4_conv3/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block4_conv3/bias' type=VarHandleOp>,
 <tf.Operation 'block4_conv3/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block5_conv1/kernel' type=VarHandleOp>,
 <tf.Operation 'block5_conv1/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block5_conv1/bias' type=VarHandleOp>,
 <tf.Operation 'block5_conv1/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block5_conv2/kernel' type=VarHandleOp>,
 <tf.Operation 'block5_conv2/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block5_conv2/bias' type=VarHandleOp>,
 <tf.Operation 'block5_conv2/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block5_conv3/kernel' type=VarHandleOp>,
 <tf.Operation 'block5_conv3/kernel/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'block5_conv3/bias' type=VarHandleOp>,
 <tf.Operation 'block5_conv3/bias/Read/ReadVariableOp' type=ReadVariableOp>,
 <tf.Operation 'NoOp' type=NoOp>,
 <tf.Operation 'Const' type=Const>,
 <tf.Operation 'serving_default_input_5' type=Placeholder>,
 <tf.Operation 'StatefulPartitionedCall' type=StatefulPartitionedCall>,
 <tf.Operation 'saver_filename' type=Placeholder>,
 <tf.Operation 'StatefulPartitionedCall_1' type=StatefulPartitionedCall>,
 <tf.Operation 'StatefulPartitionedCall_2' type=StatefulPartitionedCall>]

so when I try to make a prediction :

in_t = sess.graph.get_tensor_by_name('serving_default_input_5:0')
out  = sess.graph.get_tensor_by_name('dense_4_1/bias/Read/ReadVariableOp:0')
...
pred = sess.run([out], feed_dict={ in_t: image}) # image has the right shape

How can I pass an image of shape (512,512,3) to my loaded saved_model?

TY in advance ^^

1 Answers

If in_t = sess.graph.get_tensor_by_name('serving_default_input_5:0') doesn't work, you can try using Placeholder_0 as that is the name given to an Input by default.

Also, not sure if you are preprocessing the Input before passing it for Prediction.

Please find the below code for pre-processing:

IMG_SIZE = 512

img_array = cv2.imread('Image.jpg')
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
new_array = new_array / 255

new_array = new_array.reshape(-1, 512, 512, 3)

Below code should work:

with tf.Session(graph=tf.Graph()) as sess:
    tf.saved_model.loader.load(
        sess,
        [tf.saved_model.tag_constants.SERVING],
        "Saved_Model"
    )

    prediction = sess.run(
        [out],
        feed_dict={'Placeholder:0': new_array})

    print(prediction)

If you still face any error, please share the complete Error Trace and we will be happy to help you.

Hope this helps. Happy Learning!

Related