TensorFlow聊天模型训练报错:Sequential层输入张量数量不符
聊天机器人训练报错解决方案
错误信息
训练时触发如下错误:
ValueError: Layer "sequential" expects 1 input(s), but it received 37 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None,) dtype=int32>, ...]
问题代码与配置
训练代码
import random import json import pickle import numpy as np import nltk from nltk.stem import WordNetLemmatizer # nltk.download('punkt') # nltk.download('wordnet') import tensorflow as tf from tensorflow import * import keras from keras import layers import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1' # 屏蔽CPU类型导致的版本错误 lemmatizer = WordNetLemmatizer() intents = json.loads(open('intents.json').read()) words = [] classes = [] documents = [] ignore_letters = ['?', '!', '.', ','] for intent in intents['intents']: for pattern in intent['patterns']: word_list = nltk.word_tokenize(pattern) words.extend(word_list) documents.append((word_list, intent['tag'])) if intent['tag'] not in classes: classes.append(intent['tag']) words = [lemmatizer.lemmatize(word) for word in words if word not in ignore_letters] words = sorted(set(words)) classes = sorted(set(classes)) pickle.dump(words, open('words.pkl', 'wb')) pickle.dump(words, open('classes.pkl', 'wb')) # 此处存在错误,应为classes training = [] output_empty = [0] * len(classes) for document in documents: bag = [] word_patterns = document[0] word_patterns = [lemmatizer.lemmatize(word.lower()) for word in word_patterns] for word in words: bag.append(1) if word in word_patterns else bag.append(0) output_row = list(output_empty) output_row[classes.index(document[1])] = 1 training.append([bag, output_row]) data_tensor = tf.ragged.constant(training) data_tensor = data_tensor.to_tensor() random.shuffle(data_tensor) data_tensor = np.array(data_tensor) train_x = list(data_tensor[:, 0]) train_y = list(data_tensor[:, 1]) # train_x = np.array(train_x, dtype=int) # train_y = np.array(train_y, dtype=int) model = tf.keras.Sequential() model.add(layers.Dense(128, input_shape=(len(train_x[0]),), activation='relu')) model.add(layers.Dropout(0.5)) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dropout(0.5)) model.add(layers.Dense(len(train_y[0]), activation='softmax')) sgd = tf.keras.optimizers.experimental.SGD(learning_rate=0.01, momentum=0.0, nesterov=True, weight_decay=None, global_clipnorm=None, ema_momentum=0.99, ema_overwrite_frequency=None, name='SGD',) model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accurancy']) # 拼写错误:accurancy -> accuracy model.fit(train_x, train_y, batch_size=5, epochs=10, verbose=1) model.save('chatbot_model.model') print("\nDone\n") model.load('chatbot_model.model') # 方法错误,应为load_model
intents.json结构示例
{"intents": [ {"tag": "greetings", "patterns": ["hello", "hey", "hi", "good day", "Greetings", "what's up?", "how is it going?"], "responses": ["Hello!", "Hey!", "What can I do for you?"] }, {"tag": "goodbye", "patterns": ["cya", "See you later", "Goodbye", "I am Leaving", "Have a Good day", "bye", "cao", "see ya"], "responses": ["Sad to see you go :(", "Talk to you later", "Goodbye!"] }, {"tag": "name", "patterns": ["what is your name", "what should i call you", "what should i call you", "what your name?", "who are you?", "who are you?", "can you tell me your name"], "responses": ["Hello!", "Hey!", "What can I do for you?"] } ]}
错误原因与修复步骤
核心错误原因
train_x和train_y被转为列表形式的一维数组,TensorFlow会将列表中的每个元素视为独立输入,导致模型收到多个输入张量,与第一层定义的单输入形状不匹配。
具体修复点
- 转换输入数据为二维numpy数组
取消注释并修正数据类型转换代码,确保输入是模型预期的二维张量:
train_x = np.array(train_x, dtype=np.float32) train_y = np.array(train_y, dtype=np.float32)
- 修正指标拼写错误
将model.compile中的'accurancy'改为正确的'accuracy':
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
- 修正模型加载方法
model.load不是合法方法,替换为TensorFlow官方加载函数:
model = tf.keras.models.load_model('chatbot_model.model')
- 修正pickle保存错误
保存classes时误存了words,修正为:
pickle.dump(classes, open('classes.pkl', 'wb'))
- 修正循环缩进问题
原代码中for intent和for pattern的内部代码没有缩进,这会导致语法错误,需按Python缩进规范调整(已在上面的代码示例中修正)。
修复后训练流程
完成上述修改后,模型将正确识别输入形状,可正常执行训练流程。
内容的提问来源于stack exchange,提问作者EinShadow
相关产品推荐
相关产品推荐

