加載模型報錯 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_fnl裏面定義輸入數據格式時,使用了稀疏向量的佔位符,而稀疏向量存儲到模型裏沒有存儲名字,導致重新加載模型會報錯。

打印出了報錯的數據的內容,可以看到 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.:
Change

sparse_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)
發佈了18 篇原創文章 · 獲贊 8 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章