You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

model.compile添加多指标时出现ValueError形状不兼容问题求助

问题描述

在TensorFlow中,model.compile原本支持传入多个评估指标,示例如下:

model.compile(loss='mean_squared_error',
              optimizer='sgd',
              metrics=[metrics.mae, metrics.categorical_accuracy])
# 或者写成
metrics=['mae', 'categorical_accuracy']

但在使用DistilBERT进行二分类序列任务时,仅指定metrics=['accuracy']时代码可正常运行,添加AUC、精确率、召回率等指标或多个指标时,会触发以下错误:

ValueError: Shapes (None, 2) and (None, 1) are incompatible

完整代码如下:

import pandas as pd
import tensorflow as tf
import transformers
from transformers import DistilBertTokenizer
from transformers import TFAutoModelForSequenceClassification
pd.set_option('display.max_colwidth', None)
MODEL_NAME = 'distilbert-base-uncased'
BATCH_SIZE = 8
N_EPOCHS = 3

tokenizer = DistilBertTokenizer.from_pretrained(MODEL_NAME)

train_encodings = tokenizer(list(X_train.values),
                        truncation=True, 
                        padding=True)
test_encodings = tokenizer(list(X_test.values),
                       truncation=True, 
                       padding=True)

train_dataset = tf.data.Dataset.from_tensor_slices((dict(train_encodings),list(y_train.values)))

test_dataset = tf.data.Dataset.from_tensor_slices((dict(test_encodings),list(y_test.values)))

test_dataset2 = test_dataset.shuffle(buffer_size=1024).take(1000).batch(16)

model = TFAutoModelForSequenceClassification.from_pretrained(MODEL_NAME)

optimizerr = tf.keras.optimizers.Adam(learning_rate=5e-5)

losss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

model.compile(optimizer=optimizerr,
          loss=losss,
          metrics=['accuracy','AUC'])

print("Evaluate Base model on test data")
results = model.evaluate(test_dataset2)
print("test loss, test acc:", results)
解决方法

错误原因

你使用的是SparseCategoricalCrossentropy损失函数,对应标签是稀疏格式(即单值整数,比如0、1),模型输出是(None, 2)维度的logits(二分类任务)。单独用accuracy时TensorFlow会自动适配为SparseCategoricalAccuracy,能处理稀疏标签和多维度logits的匹配;但AUC、精确率等指标默认期望输入是与标签维度一致的格式(比如one-hot编码),因此出现维度不兼容的错误。

提供两种可行的解决方式:


方案一:修改指标,适配稀疏标签

直接使用TensorFlow提供的稀疏标签专用指标类,或给通用指标指定适配参数:

  1. 对于AUC:设置from_logits=True(匹配模型输出的logits)和num_labels=2(二分类)
  2. 对于精确率、召回率:使用SparseCategoricalPrecision和SparseCategoricalRecall,指定num_classes=2
  3. 替换model.compile中的metrics参数:
model.compile(
    optimizer=optimizerr,
    loss=losss,
    metrics=[
        tf.keras.metrics.SparseCategoricalAccuracy(name="accuracy"),
        tf.keras.metrics.AUC(from_logits=True, num_labels=2, name="auc"),
        tf.keras.metrics.SparseCategoricalPrecision(num_classes=2, name="precision"),
        tf.keras.metrics.SparseCategoricalRecall(num_classes=2, name="recall")
    ]
)

方案二:转换标签为one-hot编码,使用分类交叉熵损失

将稀疏标签转换为one-hot格式,让标签维度与模型输出一致:

  1. 转换标签:
y_train_onehot = tf.one_hot(y_train.values, depth=2)
y_test_onehot = tf.one_hot(y_test.values, depth=2)
  1. 构建数据集时使用转换后的标签:
train_dataset = tf.data.Dataset.from_tensor_slices((dict(train_encodings), y_train_onehot))
test_dataset = tf.data.Dataset.from_tensor_slices((dict(test_encodings), y_test_onehot))
  1. 修改损失函数为CategoricalCrossentropy:
losss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
  1. 此时model.compile的metrics可以直接使用字符串形式:
model.compile(optimizer=optimizerr,
              loss=losss,
              metrics=['accuracy','AUC', 'Precision', 'Recall'])

内容的提问来源于stack exchange,提问作者Injarapu Sri Sharanya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 01:33:24