如何用TensorFlow模型对编码后的句子进行正确预测
解决方案
你的问题主要出在三个地方:预测时的输入格式错误、未保留标签编码器实例、未将模型输出的概率数组转换为原始标签。以下是具体修改步骤和完整代码:
关键修改点
- 保存LabelEncoder实例:原
label_encoding函数仅返回编码后的标签,现在需同时返回编码器实例,才能将预测得到的索引转回原始标签。 - 修正预测输入格式:
encode_sentences接收的是句子列表,预测单个句子时必须将其放入列表传入,否则函数会把字符串拆成单个字符处理,导致维度错误。 - 解析模型输出:模型用
softmax输出的是每个类别的概率,需先找到概率最高的类别索引,再通过编码器映射回原始标签。
修改后的完整代码
import numpy as np import tensorflow as tf from tensorflow import keras import pandas as pd import sqlite3 from sklearn.preprocessing import LabelEncoder import spacy from sklearn.model_selection import train_test_split nlp = spacy.load('en_core_web_lg') embedding_dim = nlp.vocab.vectors_length def read_database(path): # Loading Data from database connection = sqlite3.connect(path) db_rows = pd.read_sql('''select intents.intent, patterns.pattern from intents, patterns where intents.id = patterns.intentid''', connection) labels = [] sentences = [] intents = [] for i in range(len(db_rows)): labels.append(db_rows["intent"][i]) if db_rows["intent"][i] not in intents: intents.append(db_rows["intent"][i]) sentences.append(db_rows["pattern"][i]) return sentences, labels, intents def label_encoding(labels): # Calculate the length of labels n_labels = len(labels) print('Number of labels :-', n_labels) le = LabelEncoder() y = le.fit_transform(labels) print('Length of y :- ', y.shape) # 返回编码器实例和编码后的标签 return y, le def encode_sentences(sentences): # Calculate number of sentences n_sentences = len(sentences) X = np.zeros((n_sentences, embedding_dim)) # Iterate over the sentences for idx, sentence in enumerate(sentences): doc = nlp(sentence) # Save the document's .vector attribute to the corresponding row in X[idx, :] = doc.vector return X sentences_train, labels_train, all_intents = read_database('./database_x.db') sentences_train = encode_sentences(sentences_train) # 接收编码后的标签和编码器 labels_train, label_encoder = label_encoding(labels_train) x_train, x_test, y_train, y_test = train_test_split(sentences_train, labels_train, test_size=0.2) model = keras.Sequential([keras.layers.Dense(16, activation='relu'), keras.layers.Dense(16, activation='relu'), keras.layers.Dense(len(all_intents), activation='softmax')]) model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.01), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=['accuracy']) model.fit(x_train, y_train, batch_size=16, epochs=100) # 预测时传入包含单个句子的列表 test_sentence = ["how can i test rf heating"] encoded_sentence = encode_sentences(test_sentence) prediction = model.predict(encoded_sentence) # 取概率最大的索引,再转成原始标签 predicted_idx = np.argmax(prediction, axis=1)[0] predicted_label = label_encoder.inverse_transform([predicted_idx])[0] print("\n预测概率数组:") print(prediction) print("\n预测的标签:") print(predicted_label)
代码说明
label_encoding函数修改:新增返回LabelEncoder实例,后续通过le.inverse_transform将索引转换为原始标签。- 预测输入修正:将单个句子放入列表中传入
encode_sentences,确保生成维度正确的向量(对应en_core_web_lg的300维词向量)。 - 预测结果解析:
np.argmax(prediction, axis=1)找出概率最高的类别索引;label_encoder.inverse_transform([predicted_idx])将索引转回原始的intent标签。
内容的提问来源于stack exchange,提问作者kaan46
相关产品推荐
相关产品推荐

