使用tflearn训练文本分类模型后,用sklearn计算Precision/Recall/F1遇报错求助
问题:TFLearn模型预测时触发形状不兼容的ValueError
问题场景
用TFLearn训练完成文本分类模型并通过model.evaluate(test_x, test_y)完成评估后,尝试调用model.predict(test_y)获取预测结果以计算Precision、Recall、F1值,触发ValueError,提示输入形状与模型输入张量形状不兼容。
训练数据构建代码
#creating our training data training = [] output = [] #create an empty array for our output output_empty = [0] * len(classes) #training set, bag of words for each sentence for doc in documents: #initialize our bag of words bag = [] #list of tokenized words for the pattern pattern_words = doc[0] # stem each word pattern_words = [stemmer.stem(word.lower()) for word in pattern_words] # create our bag of words array for w in words: bag.append(1) if w in pattern_words else bag.append(0) # output is a '0' for each tag and '1' for current tag output_row = list(output_empty) output_row[classes.index(doc[1])] = 1 training.append([bag, output_row]) # shuffle our features and turn into np.array random.shuffle(training) training = np.array(training) # create train and test lists train_x = list(training[:,0]) train_y = list(training[:,1])
数据集划分代码
from sklearn.model_selection import train_test_split train_x, test_x, train_y, test_y = train_test_split(train_x, train_y, test_size=0.10, random_state=10, stratify=train_y)
数组转换代码
train_x = np.array(train_x) train_y = np.array(train_y) test_x=np.array(test_x) test_y = np.array(test_y)
模型构建与训练代码
net = tflearn.input_data(shape=[None, len(train_x[0])]) net = tflearn.fully_connected(net, 128) net = tflearn.fully_connected(net, len(train_y[0]), activation='softmax') net = tflearn.regression(net) # Define model and setup tensorboard model = tflearn.DNN(net, tensorboard_dir='tflearn_logs') model.fit(train_x, train_y, n_epoch=10, batch_size=8, show_metric=True ) model.evaluate(test_x, test_y)
错误触发代码
predict_y = model.predict(test_y)
报错信息
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-56-33f24cfe9a52> in <module> ----> 1 predicted_y = model.predict(test_y) 2 #y_hatclass = model.predict_classes(test_x) 3 frames /usr/local/lib/python3.8/dist-packages/tensorflow/python/client/session.py in _run(self, handle, fetches, feed_dict, options, run_metadata) 1162 if (not is_tensor_handle_feed and 1163 not subfeed_t.get_shape().is_compatible_with(np_val.shape)): -> 1164 raise ValueError( 1165 f'Cannot feed value of shape {str(np_val.shape)} for Tensor ' 1166 f'{subfeed_t.name}, which has shape ' ValueError: Cannot feed value of shape (143, 7) for Tensor InputData/X:0, which has shape (?, 55)
问题原因
- 模型输入层定义为
shape=[None, len(train_x[0])],即需要接收55维的文本特征向量 - 错误地将**测试集标签test_y(形状(143,7)的one-hot编码向量)**作为输入喂给模型,维度完全不匹配,触发形状不兼容错误
解决方案
1. 修正预测输入
将model.predict(test_y)改为model.predict(test_x),传入测试集特征而非标签
2. 转换预测结果格式
模型输出的是softmax概率分布,需要转换为类别索引;同时将one-hot编码的test_y也转换为类别索引,才能用sklearn计算指标
完整修正代码
import numpy as np from sklearn.metrics import precision_score, recall_score, f1_score # 用测试集特征做预测 predict_y = model.predict(test_x) # 将softmax概率转换为类别索引 predict_classes = np.argmax(predict_y, axis=1) # 将one-hot编码的真实标签转换为类别索引 true_classes = np.argmax(test_y, axis=1) # 计算评估指标(average参数可根据需求调整为'macro'/'micro'/'weighted') precision = precision_score(true_classes, predict_classes, average='weighted') recall = recall_score(true_classes, predict_classes, average='weighted') f1 = f1_score(true_classes, predict_classes, average='weighted') print(f"Precision: {precision:.4f}") print(f"Recall: {recall:.4f}") print(f"F1 Score: {f1:.4f}")
内容的提问来源于stack exchange,提问作者Jul
相关产品推荐
相关产品推荐

