如下该怎么解决tensorflow报错问题呢
报错信息
ValueError: Could not find matching concrete function to call loaded from the SavedModel. Got:
Positional arguments (2 total):
* 'x:0' shape=(1, 33) dtype=int32>
* 'hidden:0' shape=(1, 1, 1024) dtype=float32>
Keyword arguments: {'training': False}
Expected these arguments to match one of the following 2 option(s):
Option 1:
Positional arguments (2 total):
* TensorSpec(shape=(None, 33), dtype=tf.int32, name='x')
* TensorSpec(shape=(None, 1024), dtype=tf.float32, name='hidden')
Keyword arguments: {'training': False}
Option 2:
Positional arguments (2 total):
* TensorSpec(shape=(None, 33), dtype=tf.int32, name='x')
* TensorSpec(shape=(None, 1024), dtype=tf.float32, name='hidden')
Keyword arguments: {'training': True}
flask 调用
rom flask import Flask, request, jsonify
import tensorflow as tf
from tensorflow import keras
import numpy as np
from datetime import datetime
from main import process, question_answer, tokenize, max_length, preprocess_question
app = Flask(__name__)
encoder = tf.saved_model.load("saved_model/encoder")
decoder = tf.saved_model.load("saved_model/decoder")
def answer_vector(question, a_max_len, q_max_len, q_index, a_index, encoder, decoder) :
attention_plot = np.zeros((a_max_len, q_max_len))
question = preprocess_question(question)
if True:
inputs = [q_index.word_index[i] for i in question.split(" ")]
inputs = keras.preprocessing.sequence.pad_sequences([inputs], maxlen=q_max_len, padding="post")
inputs = tf.convert_to_tensor(inputs)
inputs = tf.bitcast(inputs, type=tf.int32)
result = ""
hidden = [tf.zeros((1, units))]
hidden = tf.bitcast(hidden, type=tf.float32)
q_out, q_hidden = encoder(inputs, hidden)
a_hidden = q_hidden
a_input = tf.expand_dims([a_index.word_index["" ]], 0)
for t in range(a_max_len) :
predictions, a_hidden, attention_weights = decoder(a_input, a_hidden, q_out)
attention_weights = tf.reshape(attention_weights, (-1,))
attention_plot[t] = attention_weights.numpy()
predicted_id = tf.argmax(predictions[0]).numpy()
result = result + a_index.index_word[predicted_id] + " "
if a_index.index_word[predicted_id] != "" :
result = result + a_index.index_word[predicted_id] + " "
else :
return result, question, attention_plot
a_input = tf.expand_dims([predicted_id], 0)
return result, question, attention_plot
#except :
#result = "######ERROR######"
#attention_plot = None
#return result, question, attention_plot
def chat(question, a_max_len, q_max_len, q_index, a_index, encoder, decoder) :
result, question, attention_plot = answer_vector(question, a_max_len, q_max_len, q_index, a_index, encoder, decoder)
return result
@app.route('/', methods=["GET", "POST"])
def test() :
if True :
if request.method == "POST" :
inputs = request.json['input']
print(inputs)
result = chat(inputs, a_max_len, q_max_len, q_index, a_index, encoder, decoder)
result = format(result)
return jsonify({"code":200, "result":result})
else :
return jsonify({"code":400, "result":"ERROR OCCOURED"})
#except BaseException :
#return jsonify({"code":400, "result":None})
if __name__ == "__main__" :
stamp = datetime.now().strftime("%Y%m%d-%H:%M:%S")
source = "./train/test.conv"
convs = process(source, None)
questions, answers = question_answer(convs)
q_vec, q_index = tokenize(questions)
a_vec, a_index = tokenize(answers)
print("voc:", q_vec)
print("tokenize:", q_index.index_word)
print("voc:", a_vec)
print("tokenize:", a_index.index_word)
q_max_len = max_length(q_vec)
a_max_len = max_length(a_vec)
BUFFER_SIZE = len(q_vec)
print("buffer size:", BUFFER_SIZE)
BATCH_SIZE = 3
steps_per_epoch = len(q_vec)//BATCH_SIZE
embedding_dim = 256
units = 1024
q_vocab_size = len(q_index.word_index) + 1
a_vocab_size = len(a_index.word_index) + 1
app.run(port=9999, debug=True)
解码器 编码器
class Encoder(tf.keras.Model) :
def __init__(self, vocab_size, embedding_dim, enc_units, batch_sz) :
super(Encoder, self).__init__()
self.batch_sz = batch_sz
self.enc_units = enc_units
self.embedding = keras.layers.Embedding(vocab_size, embedding_dim)
self.gru = keras.layers.GRU(self.enc_units, return_sequences=True, return_state=True, recurrent_initializer="glorot_uniform")
@tf.function
def call(self, x, hidden) :
x = self.embedding(x)
output, state = self.gru(x, initial_state=hidden)
return output, state
def initialize_hidden_state(self) :
return tf.zeros((self.batch_sz, self.enc_units))
class Decoder(tf.keras.Model) :
def __init__(self, vocab_size, embedding_dim, dec_units, batch_sz) :
super(Decoder, self).__init__()
self.batch_sz = batch_sz
self.dec_units = dec_units
self.embedding = layers.Embedding(vocab_size, embedding_dim)
self.gru = layers.GRU(self.dec_units, return_sequences=True, return_state=True, recurrent_initializer="glorot_uniform")
self.fc = layers.Dense(vocab_size)
self.W1 = layers.Dense(units)
self.W2 = layers.Dense(units)
self.V = layers.Dense(1)
@tf.function
def call(self, x, hidden, enc_output) :
hidden_with_time_axis = tf.expand_dims(hidden, 1)
score = self.V(tf.nn.tanh(self.W1(enc_output) + self.W2(hidden_with_time_axis)))
attention_weights = tf.nn.softmax(score, axis=1)
context_vector = attention_weights * enc_output
context_vector = tf.math.reduce_sum(context_vector, axis=1)
x = self.embedding(x)
x = tf.concat([tf.expand_dims(context_vector, 1), x],axis=-1)
output, state = self.gru(x)
output = tf.reshape(output, (-1, output.shape[2]))
x = self.fc(output)
return x, state, attention_weights
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个报错信息意味着在加载 SavedModel 时,无法找到与输入张量匹配的适当函数。每个已保存的函数都只接受特定的输入函数签名,并且当 SavedModel 中适当的函数无法匹配输入时,就会发生这种情况。
在这种情况下,我们根据报错信息可以看到,已保存的函数期望 training
关键字参数值为 True
,而我们的调用代码中使用的是默认值 False
。
为了解决这个问题,我们可以在 flask 调用 decoder
函数时将 training
参数指定为 True
。下面是修改后的代码:
def answer_vector(question, a_max_len, q_max_len, q_index, a_index, encoder, decoder) :
attention_plot = np.zeros((a_max_len, q_max_len))
question = preprocess_question(question)
if True:
inputs = [q_index.word_index[i] for i in question.split(" ")]
inputs = keras.preprocessing.sequence.pad_sequences([inputs], maxlen=q_max_len, padding="post")
inputs = tf.convert_to_tensor(inputs)
inputs = tf.bitcast(inputs, type=tf.int32)
result = ""已黑化的小白
hidden = [tf.zeros((1, units))]
hidden = tf.bitcast(hidden, type=tf.float32)
q_out, q_hidden = encoder(inputs, hidden)
a_hidden = q_hidden
a_input = tf.expand_dims([a_index.word_index["<start>"]], 0)
for t in range(a_max_len) :
predictions, a_hidden, attention_weights = decoder(a_input, a_hidden, q_out, training=True) # 修改这里
attention_weights = tf.reshape(attention_weights, (-1,))
attention_plot[t] = attention_weights.numpy()
predicted_id = tf.argmax(predictions[0]).numpy()
result = result + a_index.index_word[predicted_id] + " "已黑化的小白
if a_index.index_word[predicted_id] != "<end>" :
result = result + a_index.index_word[predicted_id] + " "已黑化的小白 else :
return result, question, attention_plot
a_input = tf.expand_dims([predicted_id], 0)
return result, question, attention_plot
像这样在调用(decoder
函数的前两个输入 a_input
和 a_hidden
后面)指定 training
参数是解决这个问题的一种简单方法,也可以使用其他方法。另外,你也需要检查你的 encoder
函数调用是否需要设置 training=True
。
希望能够帮助你解决这个问题。
如果我的回答解决了您的问题,请采纳!
我大致看了下,你是要接收POST请求并调用chat函数从TensorFlow模型返回结果,检查下chat函数时传递的参数和返回值
【TensorFlow】TensorFlow报错及解决方法(持续更新中)
可以借鉴下
https://blog.csdn.net/qq_36643449/article/details/124542494
Flask框架实现服务端,这个框架我是听我同学说的,因为他们公司就是使用这种方法部署深度学习模型的,不过我们项目当中没有用到,有兴趣的同学可以自己去了解一下这个Flask框架,这里不累述了。
从错误信息看,SavedModel加载失败,无法找到匹配的concrete function。这通常是由以下几个原因导致的:
在你的代码中,SavedModel的encoder和decoder模型很可能是在训练过程中保存的,它们的输入是训练数据中的输入和输出向量。而在推理时,传入的输入是用户输入的自然语言question字符串,导致输入不匹配,从而加载失败。
解决方法是在保存SavedModel时同时保存推理所需的输入输出签名,在推理时加载这个签名进行推理。
如果训练模型时使用的TensorFlow版本与推理时不同,可能由于TensorFlow版本更新导致SavedModel模式变化,无法加载。
解决方法是确保训练和推理使用相同的TensorFlow版本。
如果训练模型时和推理时使用的模型代码不同,会导致推理时构建的计算图与SavedModel不一致,无法加载。
解决方法是确保训练和推理使用完全相同的模型代码。
综上,我的建议是:
在保存SavedModel时同时保存用于推理的输入输出签名。
确保训练和推理使用相同的TensorFlow版本。
确保训练和推理使用完全相同的模型代码。
检查encoder和decoder模型的输入是否与推理代码提供的question输入匹配。如果不匹配,需要对输入进行处理使其匹配。
希望以上建议能帮助你解决TensorFlow SavedModel加载失败的问题。如有任何其他疑问,欢迎在评论中提出。
引用chatGPT作答,这个错误信息表示TensorFlow无法在保存的模型中找到一个匹配的具体函数来调用。你需要检查你在使用的代码和保存的模型之间的兼容性。
从报错信息来看,你传递的参数与期望的参数不匹配。期望的参数如下:
Option 1:
Positional arguments (2 total):
* TensorSpec(shape=(None, 33), dtype=tf.int32, name='x')
* TensorSpec(shape=(None, 1024), dtype=tf.float32, name='hidden')
Keyword arguments: {'training': False}
Option 2:
Positional arguments (2 total):
* TensorSpec(shape=(None, 33), dtype=tf.int32, name='x')
* TensorSpec(shape=(None, 1024), dtype=tf.float32, name='hidden')
Keyword arguments: {'training': True}
这意味着您应该检查您正在加载的编码器和解码器的输入参数和保存的模型中的期望参数之间的差异。您需要确保这些参数是兼容的,并且在您的代码中的调用中使用了正确的参数。
您可以检查您的编码器和解码器的输入参数,以确保它们与期望的参数匹配。如果它们不匹配,您可以将它们更改为匹配期望的参数。如果它们匹配但问题仍然存在,则您需要检查您的代码中调用这些模型的方式。