如何解决BERT HF模型的ValueError: too many values to unpack (expected 2)?
BERT多文本分类预处理错误解决
问题描述
构建包含两列文本和标签的虚拟数据集,使用Hugging Face的BERT模型做分类。基础版本代码运行正常,但在分词器中添加padding=True、truncation=True、max_length=30和return_tensors="tf"参数后,出现如下错误:
ValueError: Exception encountered when calling layer 'bert' (type TFBertMainLayer). in user code: File "/usr/local/lib/python3.10/dist-packages/transformers/modeling_tf_utils.py", line 1557, in run_call_with_unpacked_inputs * return func(self, **unpacked_inputs) File "/usr/local/lib/python3.10/dist-packages/transformers/models/bert/modeling_tf_bert.py", line 766, in call * batch_size, seq_length = input_shape ValueError: too many values to unpack (expected 2)
出错代码片段:
def tokenize_dataset(df): return tokenizer(df['text_column1'], df['text_column2'], padding=True,truncation=True,max_length=30, return_tensors="tf") import pandas as pd df = pd.DataFrame({'text_column1': text_column1, 'text_column2': text_column2, 'label': labels}) df = Dataset.from_pandas(df).map(tokenize_dataset) tf_train = model2.prepare_tf_dataset(df, batch_size=4, shuffle=True, tokenizer=tokenizer) model2.compile(optimizer=Adam(3e-5)) model2.fit(tf_train)
错误原因
核心问题出在return_tensors="tf"参数:
Dataset.map()函数要求返回Python列表/NumPy数组格式的数据,而return_tensors="tf"会让分词器直接返回TensorFlow的Tensor对象,存入Dataset后会导致数据维度异常。- 后续
prepare_tf_dataset处理时,输入张量会多出一个冗余维度(比如从预期的(batch_size, seq_len)变成(batch_size, 1, seq_len))。 - BERT模型输入层期望二维形状
(batch_size, seq_length),实际拿到三维形状后,执行batch_size, seq_length = input_shape时无法解包,触发报错。
另外,prepare_tf_dataset中重复传入tokenizer属于冗余操作——已提前完成分词,重复传入会导致二次处理干扰数据结构。
解决方法
1. 移除return_tensors="tf"参数
map阶段只需返回普通字典格式结果,prepare_tf_dataset会自动将数据转换为TensorFlow所需的Tensor格式。
2. 移除prepare_tf_dataset中的tokenizer参数
避免重复分词导致的数据异常。
3. 显式指定损失函数(推荐)
虽然TensorFlow可自动推断损失,但显式指定SparseCategoricalCrossentropy(适配整数标签)并设置from_logits=True(BERT分类头默认返回logits),逻辑更清晰。
修正后的完整代码
def tokenize_dataset(df): # 保留预处理参数,移除return_tensors="tf" return tokenizer(df['text_column1'], df['text_column2'], padding=True, truncation=True, max_length=30) import pandas as pd df = pd.DataFrame({'text_column1': text_column1, 'text_column2': text_column2, 'label': labels}) df = Dataset.from_pandas(df).map(tokenize_dataset) # 移除冗余的tokenizer参数 tf_train = model2.prepare_tf_dataset(df, batch_size=4, shuffle=True) from tensorflow.keras.optimizers import Adam model2.compile( optimizer=Adam(3e-5), loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'] # 添加评估指标,便于监控训练效果 ) model2.fit(tf_train)
内容的提问来源于stack exchange,提问作者krishna kaushik
相关产品推荐
相关产品推荐

