I trained a resnet with tf.estimator, the model was saved during the training process. The saved files consist of .data
, .index
and .meta
. I'd like to load this model back and get predictions for new images. The data was fed to the model during training using tf.data.Dataset
. I have closely followed the resnet implementation given here.
I would like to restore the model and feed inputs to the nodes using a feed_dict.
First attempt
#rebuild input pipeline
images, labels = input_fn(data_dir, batch_size=32, num_epochs=1)
#rebuild graph
prediction= imagenet_model_fn(images,labels,{'batch_size':32,'data_format':'channels_first','resnet_size':18},mode = tf.estimator.ModeKeys.EVAL).predictions
saver = tf.train.Saver()
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(r'./model')
saver.restore(sess, ckpt.model_checkpoint_path)
while True:
try:
pred,im= sess.run([prediction,images])
print(pred)
except tf.errors.OutOfRangeError:
break
I fed a dataset which was evaluated on the same model using classifier.evaluate
, but the above method gives wrong predictions. The model gives same class and probability, 1.0, for all images.
Second attempt
saver = tf.train.import_meta_graph(r'.\resnet\model\model-3220.meta')
sess = tf.Session()
saver.restore(sess,tf.train.latest_checkpoint(r'.\resnet\model'))
graph = tf.get_default_graph()
inputImage = graph.get_tensor_by_name('image:0')
logits= graph.get_tensor_by_name('logits:0')
#Get prediction
print(sess.run(logits,feed_dict={inputImage:newimage}))
This also gives wrong predictions compared to classifier.evaluate
. I can even run sess.run(logits)
without a feed_dict
!
Third attempt
def serving_input_fn():
receiver_tensor = {'feature': tf.placeholder(shape=[None, 384, 256, 3], dtype=tf.float32)}
features = {'feature': receiver_tensor['images']}
return tf.estimator.export.ServingInputReceiver(features, receiver_tensor)
It fails with
Traceback (most recent call last):
File "imagenet_main.py", line 213, in <module>
tf.app.run(argv=[sys.argv[0]] + unparsed)
File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\platform\app.py", line 124, in run
_sys.exit(main(argv))
File "imagenet_main.py", line 204, in main
resnet.resnet_main(FLAGS, imagenet_model_fn, input_fn)
File "C:\Users\Photogauge\Desktop\iprings_images\models-master\models-master\official\resnet\resnet.py", line 527, in resnet_main
classifier.export_savedmodel(export_dir_base=r"C:\Users\Photogauge\Desktop\iprings_images\models-master\models-master\official\resnet\export", serving_input_receiver_fn=serving_input_fn)
File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\estimator\estimator.py", line 528, in export_savedmodel
config=self.config)
File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\estimator\estimator.py", line 725, in _call_model_fn
model_fn_results = self._model_fn(features=features, **kwargs)
File "imagenet_main.py", line 200, in imagenet_model_fn
loss_filter_fn=None)
File "C:\Users\Photogauge\Desktop\iprings_images\models-master\models-master\official\resnet\resnet.py", line 433, in resnet_model_fn
tf.argmax(labels, axis=1), predictions['classes'])
File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\util\deprecation.py", line 316, in new_func
return func(*args, **kwargs)
File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\ops\math_ops.py", line 208, in argmax
return gen_math_ops.arg_max(input, axis, name=name, output_type=output_type)
File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\ops\gen_math_ops.py", line 508, in arg_max
name=name)
File "C:\Users\Photogauge\Anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 528, in _apply_op_helper
(input_name, err))
ValueError: Tried to convert 'input' to a tensor and failed. Error: None values not supported.
The code I used for training and building the model is as below:
Specification for parsing the dataset:
def parse_record(raw_record, is_training):
keys_to_features = {
'image/encoded':
tf.FixedLenFeature((), tf.string, default_value=''),
'image/class/label':
tf.FixedLenFeature([], dtype=tf.int64, default_value=-1),
}
parsed = tf.parse_single_example(raw_record, keys_to_features)
image = tf.image.decode_image(
tf.reshape(parsed['image/encoded'], shape=[]),3)
image = tf.image.convert_image_dtype(image, dtype=tf.float32)
label = tf.cast(
tf.reshape(parsed['image/class/label'], shape=[]),
dtype=tf.int32)
return image, tf.one_hot(label,2)
The following function parses the data and creates batches for training
def input_fn(is_training, data_dir, batch_size, num_epochs=1):
dataset = tf.data.Dataset.from_tensor_slices(
filenames(is_training, data_dir))
if is_training:
dataset = dataset.shuffle(buffer_size=_FILE_SHUFFLE_BUFFER)
dataset = dataset.flat_map(tf.data.TFRecordDataset)
dataset = dataset.map(lambda value: parse_record(value, is_training),
num_parallel_calls=5)
dataset = dataset.prefetch(batch_size)
if is_training:
dataset = dataset.shuffle(buffer_size=_SHUFFLE_BUFFER)
dataset = dataset.repeat(num_epochs)
dataset = dataset.batch(batch_size)
iterator = dataset.make_one_shot_iterator()
images, labels = iterator.get_next()
return images, labels
A classifier is created as below for training on train set and evaluation on validation set
classifier = tf.estimator.Estimator(
model_fn=model_function, model_dir=flags.model_dir, config=run_config,
params={
'resnet_size': flags.resnet_size,
'data_format': flags.data_format,
'batch_size': flags.batch_size,
})
#Training cycle
classifier.train(
input_fn=lambda: input_function(
training_phase=True, flags.data_dir, flags.batch_size, flags.epochs_per_eval),
hooks=[logging_hook])
# Evaluate the model
eval_results = classifier.evaluate(input_fn=lambda: input_function(
training_phase=False, flags.data_dir, flags.batch_size))
This is how I tried to load and get predictions from the model.
What is the right way to restore a saved model and perform inference on it. I want to feed images directly without using tf.data.Dataset
.
Update
The value of
ckpt
is after runningckpt = tf.train.get_checkpoint_state(r'./model')
ismodel_checkpoint_path: "./model\model.ckpt-5980" all_model_checkpoint_paths: "./model\model.ckpt-5060" all_model_checkpoint_paths: "./model\model.ckpt-5061" all_model_checkpoint_paths: "./model\model.ckpt-5520" all_model_checkpoint_paths: "./model\model.ckpt-5521" all_model_checkpoint_paths: "./model\model.ckpt-5980"
The output is same when I try `saver.restore(sess, tf.train.latest_checkpoint(r'.\resnet\model'))
Passing in full path to
saver.restore
gives the same output In all cases the same model,model.ckpt-5980
was restored