原帖报错行是 torch.tensor(train_labels.tolist()),标签实际是 notr、negative、positive 字符串:
ValueError: too many dimensions 'str'
失败行已把问题缩到目标标签
input_ids 和 attention_mask 是数值序列,原题在构造 train_y 时才遇到字符串维数错误。notr、negative、positive 是类别名称,需要稳定编码,不应该作为文本再分词。先核对拼写、缺失值与样本顺序,再创建 long 目标。
这次失败不在文本 tokenizer,也没有进入 BERT。字符串类别要先编码成数值目标,并保证训练、验证、模型输出使用同一份映射。
在构造 train_y 前检查:
print("josh050608")
print("label dtype:", train_labels.dtype)
print("label counts:", train_labels.value_counts(dropna=False).to_dict())
下面保留原帖的 notr 拼写,将三类显式编码;如果它其实是数据错误,应先统一清洗,而不是悄悄另建一个类别:
import torch
label_to_id = {
"negative": 0, "notr": 1, "positive": 2}
encoded = train_labels.map(label_to_id)
if encoded.isna().any():
raise ValueError("发现缺失或未映射的标签,请先核对原始数据")
train_y = torch.tensor(encoded.to_numpy(), dtype=torch.long)
验证集和测试集复用 label_to_id。BERT 分类头应输出 3 个 logits,目标为 [N] long;模型保存时也保存 id2label/label2id 或等价映射,预测的类别顺序才不会丢失。
不要把 train_labels 当成待 tokenizer 的输入文本;真正句子继续按 tokenizer 生成 input_ids、attention_mask。原帖这两项已经能构造张量,应该把故障范围限制在目标编码。
验证 train_y 与 tokenized 训练样本数一致,编号范围为 0 到 2,并抽查几行字符串与编号对应关系。再完成一个 batch 的前向与损失,不能只看 torch.tensor 不再报错。
映射后做一次可逆检查
下面不依赖 BERT 或 pandas,使用原题三种标签名演示编号与类别名称的往返,以及未知值检查:
import torch
names = ["notr", "negative", "positive", "notr"]
label_to_id = {
"negative": 0, "notr": 1, "positive": 2}
id_to_label = {
index: name for name, index in label_to_id.items()}
unknown = set(names) - set(label_to_id)
if unknown:
raise ValueError(f"未映射标签: {unknown}")
target = torch.tensor([label_to_id[name] for name in names], dtype=torch.long)
assert target.shape == (4,)
assert [id_to_label[index] for index in target.tolist()] == names
head = torch.nn.Linear(5, len(label_to_id))
logits = head(torch.randn(len(names), 5))
loss = torch.nn.functional.cross_entropy(logits, target)
loss.backward()
assert head.weight.grad is not None
print("encoded labels/loss:", target.tolist(), loss.item())
这验证标签与三分类头的契约,不验证真实 BERT 编码或情感准确率。原数据中的 notr 应按业务定义确认;如果它是中性类别的既有名称就保留,如果是脏数据则明确清洗,不能静默换成另一个拼写。
训练、验证与推理复用同一映射,保存模型时记录 label2id/id2label。将 DataFrame 打乱或划分后,tokenized 样本与标签应按相同索引对齐,不能分别 reset_index 后默认还对应。
验收抽查几条原文本、字符串标签和编号,再检查 [N,3] logits 与 [N] long 目标,并完成一个 batch 的损失和反向。tensor 构造成功只证明类型转换完成,不能证明标签配对正确。
参考:原始求助帖;技术依据:CrossEntropyLoss(2.5)、Transformers BERT(4.46)、pandas 2.2 to_numpy。