微调西班牙语RoBERTa情感分类模型后,如何在验证/测试集上评估性能并解决形状不匹配错误?
如何评估微调后的西班牙语RoBERTa模型(解决TensorFlow形状不匹配错误)
你遇到的形状不匹配问题,核心原因是你的TensorFlow数据集没有做批量处理——模型在训练和评估时期望接收批量数据,但当前的train_dataset、val_dataset、test_dataset都是单样本的数据集,导致标签形状((1,))和模型输出的logits形状((batch_size, 3))不匹配。下面是完整的解决步骤和优化后的代码:
第一步:修复数据集的批量处理问题
在创建TensorFlow数据集时,必须为每个数据集添加.batch()操作,确保模型能接收批量输入。修改你预处理代码的最后部分:
# 从编码创建TensorFlow数据集,并添加批量处理 batch_size = 64 train_dataset = tf.data.Dataset.from_tensor_slices((dict(train_encodings), train_labels)).shuffle(1000).batch(batch_size) val_dataset = tf.data.Dataset.from_tensor_slices((dict(val_encodings), val_labels)).batch(batch_size) test_dataset = tf.data.Dataset.from_tensor_slices((dict(test_encodings), test_labels)).batch(batch_size)
这样每个数据集返回的都是批量的样本和标签,标签形状会变成(batch_size,),和模型输出的(batch_size, 3) logits形状匹配。
第二步:带验证集的模型训练
现在可以正常在fit中加入validation_data,训练过程中会自动输出验证集的指标:
# 使用原生TensorFlow训练 from transformers import TFAutoModelForSequenceClassification ## 模型定义 model = TFAutoModelForSequenceClassification.from_pretrained( "BSC-TeMU/roberta-base-bne", from_pt=True, num_labels=3 ) ## 模型编译 optimizer = tf.keras.optimizers.Adam(learning_rate=5e-5) loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True) metric = tf.metrics.SparseCategoricalAccuracy() model.compile(optimizer=optimizer, loss=loss, metrics=[metric]) ## 拟合数据(加入验证集) history = model.fit( train_dataset, validation_data=val_dataset, epochs=5 )
训练时你会看到类似这样的输出,包含训练集和验证集的loss与准确率:
Epoch 1/5 16/16 [==============================] - 37s 1s/step - loss: 1.0225 - sparse_categorical_accuracy: 0.4857 - val_loss: 0.8912 - val_sparse_categorical_accuracy: 0.5621 ...
第三步:在测试集上评估模型性能
批量处理后的测试集可以直接用model.evaluate()获取基础指标,如果你需要更详细的评估结果(比如混淆矩阵、分类报告),可以先获取模型预测结果再计算:
基础评估(Loss和准确率)
# 评估测试集 test_results = model.evaluate(test_dataset) print(f"Test Loss: {test_results[0]:.4f}") print(f"Test Accuracy: {test_results[1]:.4f}")
详细评估(混淆矩阵、分类报告)
import numpy as np from sklearn.metrics import classification_report, confusion_matrix # 获取测试集的真实标签和模型预测标签 true_labels = [] pred_labels = [] # 遍历测试集批量数据 for batch in test_dataset: inputs, labels = batch # 获取模型预测的logits,转换为类别 logits = model(inputs) preds = np.argmax(logits.logits, axis=1) # 收集真实标签和预测标签 true_labels.extend(labels.numpy()) pred_labels.extend(preds) # 反转标签映射字典,方便读取分类报告 label_map = {0: 'NEU', 1: 'N', 2: 'P'} true_labels_names = [label_map[l] for l in true_labels] pred_labels_names = [label_map[l] for l in pred_labels] # 输出分类报告 print("分类报告:") print(classification_report(true_labels_names, pred_labels_names)) # 输出混淆矩阵 print("混淆矩阵:") print(confusion_matrix(true_labels_names, pred_labels_names, labels=['NEU', 'N', 'P']))
这样你就能全方位了解模型在测试集上的性能,包括每个类别的精确率、召回率和F1值。
内容的提问来源于stack exchange,提问作者LeLuc
相关产品推荐
相关产品推荐

