加载模型报错 The name '' looks like an (invalid) Operation name, not a Tensor.
使用estimator.export_saved_model('saved_model', serving_input_receiver_fn)
导出模型之后,再使用tf.contrib.predictor.from_saved_model
加载模型报错:ValueError: The name '' looks like an (invalid) Operation name, not a Tensor. Tensor names must be of the form "<op_name>:<output_index>".
报错详细内容:
INFO:tensorflow:Restoring parameters from saved_model/1577241037/variables/variables
Traceback (most recent call last):
File "serve.py", line 241, in <module>
predict_fn = tf.contrib.predictor.from_saved_model(latest)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/contrib/predictor/predictor_factories.py", line 153, in from_saved_model
config=config)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/contrib/predictor/saved_model_predictor.py", line 162, in __init__
for k, v in input_names.items()}
File "/usr/local/lib/python3.6/dist-packages/tensorflow/contrib/predictor/saved_model_predictor.py", line 162, in <dictcomp>
for k, v in input_names.items()}
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py", line 3666, in get_tensor_by_name
return self.as_graph_element(name, allow_tensor=True, allow_operation=False)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py", line 3490, in as_graph_element
return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py", line 3564, in _as_graph_element_locked
raise ValueError(err_msg)
ValueError: The name '' looks like an (invalid) Operation name, not a Tensor. Tensor names must be of the form "<op_name>:<output_index>".
解决方法一
查了一下网上资料,是serving_input_receiver_fn
l里面定义输入数据格式时,使用了稀疏向量的占位符,而稀疏向量存储到模型里没有存储名字,导致重新加载模型会报错。
打印出了报错的数据的内容,可以看到 label_ids 对应的名字是空的,而label_ids在我的代码中是稀疏向量。其他普通向量的名字都存在。
INFO:tensorflow:Restoring parameters from saved_model\1577241037\variables\variables
{('segment_ids', 'segment_ids:0'), ('input_ids', 'input_ids:0'), ('label_ids', ''), ('input_mask', 'input_mask:0')}
{('probabilities', 'loss/Sigmoid:0')}
names
Traceback (most recent call last):
File ".\serve.py", line 246, in <module>
predict_fn = tf.contrib.predictor.from_saved_model(latest)
File "C:\Users\shaw\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\contrib\predictor\predictor_factories.py", line 153, in from_saved_model
config=config)
File "C:\Users\shaw\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\contrib\predictor\saved_model_predictor.py", line 165, in __init__
for k, v in input_names.items()}
File "C:\Users\shaw\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\contrib\predictor\saved_model_predictor.py", line 165, in <dictcomp>
for k, v in input_names.items()}
File "C:\Users\shaw\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 3654, in get_tensor_by_name
return self.as_graph_element(name, allow_tensor=True, allow_operation=False)
File "C:\Users\shaw\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 3478, in as_graph_element
return self._as_graph_element_locked(obj, allow_tensor, allow_operation)
File "C:\Users\shaw\AppData\Local\Programs\Python\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 3552, in _as_graph_element_locked
raise ValueError(err_msg)
ValueError: The name '' looks like an (invalid) Operation name, not a Tensor. Tensor names must be of the form "<op_name>:<output_index>".
可以参考链接内容解决,大致是把一个稀疏向量分解成三部分分别存储:
[Feature Request]:Assign the name to SaprseTensor when build_tensor_info of it #22396
The problem can be solved by exporting the three dense tensor of the Sparse Tensor instead of exporting the Sparse Tensor itself, e.g.:
Changesparse_output_tensor_info=tf.saved_model.utils.build_tensor_info(predict)
outputs = {‘output’:sparse_output_tensor_info}to
indices_output_tensor_info = tf.saved_model.utils.build_tensor_info(predict.indices)
values_output_tensor_info = tf.saved_model.utils.build_tensor_info(predict.values)
dense_shape_output_tensor_info = tf.saved_model.utils.build_tensor_info(predict.dense_shape)
outputs = {‘indices’:indices_output_tensor_info,‘values’:values_output_tensor_info,‘dense_shape’:dense_shape_output_tensor_info}Well I guess it could be an easy fix by redirecting the correct name of SparseTensor when predicting, but I am not sure.
解决方法二
我的粗暴的解决方法是,不使用稀疏向量占位符tf.sparse_placeholder
,使用普通tf.placeholder
。也不再报错。
def serving_input_receiver_fn():
"""Serving input_fn that builds features from placeholders
Returns
-------
tf.estimator.export.ServingInputReceiver
"""
input_ids = tf.placeholder(dtype=tf.int32, shape=[None,FLAGS.max_seq_length], name='input_ids')
input_mask = tf.placeholder(dtype=tf.int32, shape=[None,FLAGS.max_seq_length], name='input_mask')
segment_ids = tf.placeholder(dtype=tf.int32, shape=[None,FLAGS.max_seq_length], name='segment_ids')
#label_ids = tf.sparse_placeholder(dtype=tf.int32, shape=[None,None], name='label_ids') # 不用这个占位符了
receiver_tensors = {'input_ids': input_ids, 'input_mask': input_mask,
'segment_ids': segment_ids} # 注释掉 , 'label_ids': label_ids}
features = {'input_ids': input_ids, 'input_mask': input_mask,
'segment_ids': segment_ids}# 注释掉, 'label_ids': label_ids}
return tf.estimator.export.ServingInputReceiver(features, receiver_tensors)