I have a code to load VGGFace pretrained ResNet model and export it to the tensorflow serving format. The snippet has worked on similar models that are not VGGFace ResNet.
import tensorflow as tf
import keras
from keras_vggface.vggface import VGGFace
tf.keras.backend.set_learning_phase(0)
CHANNELS = 3
model = VGGFace(model='resnet50')
model.compile(
loss=keras.losses.categorical_crossentropy,
optimizer='adam',
metrics=['accuracy'])
model.save('models/VGGFaceResnet50_celebrity_classifier.h5')
def serving_input_receiver_fn():
def decode_and_resize(image_str_tensor):
"""Decodes jpeg string, resizes it and raeturns a uint8 tensor."""
image = tf.image.decode_jpeg(image_str_tensor, channels=CHANNELS)
image = tf.cast(image, dtype=tf.uint8)
return image
# Optional; currently necessary for batch prediction.
key_input = tf.placeholder(tf.string, shape=[None])
key_output = tf.identity(key_input)
input_ph = tf.placeholder(tf.string, shape=[None], name='image_binary')
images_tensor = tf.map_fn(
decode_and_resize, input_ph, back_prop=False, dtype=tf.uint8)
images_tensor = tf.image.convert_image_dtype(images_tensor, dtype=tf.float32)
return tf.estimator.export.ServingInputReceiver(
{'input_1': images_tensor},
{'bytes': input_ph})
KERAS_MODEL_PATH='models/VGGFaceResnet50_celebrity_classifier.h5'
EXPORT_PATH='serving_model'
# If you are invoking this from your training code, use `keras_model=model` instead.
estimator = tf.keras.estimator.model_to_estimator(
keras_model_path=KERAS_MODEL_PATH)
estimator.export_savedmodel(
EXPORT_PATH,
serving_input_receiver_fn=serving_input_receiver_fn
)
However, I get the following error:
ValueError Traceback (most recent call last)
<ipython-input-1-edfbc77c298a> in <module>
44 estimator.export_savedmodel(
45 EXPORT_PATH,
---> 46 serving_input_receiver_fn=serving_input_receiver_fn
47 )
...
ValueError: The last dimension of the inputs to `Dense` should be defined. Found `None`.
I checked the model summary and I don't see any None
in the last dimension. Why is there an error?
Constructor of the VGGFace
is defined as: def VGGFace(include_top=True, model='vgg16', weights='vggface', input_tensor=None, input_shape=None, pooling=None, classes=None)
. The size of the last dimension is computed based on the input_shape
, i.e. if it is None
last dimension size will be None
as well.