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

AraBertV2分类任务报错:Dimension specified as 0 but tensor has no dimensions

问题分析与修复方案

核心错误原因

  • 张量维度不匹配:tokenizer.encode_plus设置return_tensors="pt"会生成**(1, max_length)**形状的张量,但torch.tensor(label)是0维标量,导致TensorDataset初始化时,各张量第一维度(样本数)不一致,触发维度检查错误。
  • 数据集构建逻辑错误:当前把每个单独样本包装成一个TensorDataset,再用random_split拆分,不符合PyTorch Dataset的使用规范,DataLoader无法正确批量加载这类嵌套的数据集。

修复后的完整代码

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification, AdamW
from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import pandas as pd

model_name = "aubmindlab/bert-base-arabertv2"
# 预训练tokenizer自带正确词汇表,无需手动指定vocab_size
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

max_length = 943

# 批量预处理所有文本,避免单个样本的维度问题
def preprocess_batch(texts, labels):
    tokens = tokenizer(
        texts.tolist(),
        max_length=max_length,
        padding="max_length",
        truncation=True,
        return_attention_mask=True,
        return_tensors="pt"
    )
    # 将标签转为一维张量,与input_ids维度匹配
    labels_tensor = torch.tensor(labels, dtype=torch.long)
    # 用所有样本的张量构建单个TensorDataset
    dataset = TensorDataset(
        tokens["input_ids"],
        tokens["attention_mask"],
        labels_tensor
    )
    return dataset

X = df["fully_cleaned_text_no_stopwords"].values
y = df["target"].values

# 构建完整数据集后再拆分
full_dataset = preprocess_batch(X, y)

train_size = int(0.6 * len(full_dataset))
test_size = len(full_dataset) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(full_dataset, [train_size, test_size])

train_dataloader = DataLoader(
    train_dataset,
    sampler=RandomSampler(train_dataset),
    batch_size=32
)
test_dataloader = DataLoader(
    test_dataset,
    sampler=SequentialSampler(test_dataset),
    batch_size=32
)

optimizer = AdamW(model.parameters(), lr=5e-5)

model.to(device)
model.train()
for epoch in range(25):
    total_loss = 0
    for batch in train_dataloader:
        input_ids = batch[0].to(device)
        attention_mask = batch[1].to(device)
        labels = batch[2].to(device)
        
        model.zero_grad()
        outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
        loss = outputs.loss
        total_loss += loss.item()
        
        loss.backward()
        optimizer.step()
    
    print(f"Epoch {epoch+1}, Average Loss: {total_loss/len(train_dataloader):.4f}")

model.eval()
y_true = []
y_pred = []
for batch in test_dataloader:
    input_ids = batch[0].to(device)
    attention_mask = batch[1].to(device)
    labels = batch[2].to(device)
    
    with torch.no_grad():
        outputs = model(input_ids, attention_mask=attention_mask)
    
    logits = outputs.logits
    predictions = torch.argmax(logits, dim=1)
    y_true.extend(labels.tolist())
    y_pred.extend(predictions.tolist())

accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)

print("Accuracy:", accuracy)
print("Precision:", precision)
print("Recall:", recall)
print("F1 score:", f1)

关键修复点说明

  • 移除手动指定的vocab_size:预训练tokenizer的词汇表大小固定,手动设置会破坏原有词汇表,导致tokenize错误。
  • 批量预处理文本:直接对所有文本调用tokenizer,避免单个样本处理的维度问题,同时提升效率。
  • 统一张量维度:将标签转换为(n_samples,)的一维张量,与input_ids、attention_mask的第一维度保持一致。
  • 修正数据集构建逻辑:用所有样本的张量构建单个TensorDataset后再拆分,符合PyTorch数据加载规范。
  • 优化训练循环:将optimizer.zero_grad()移到batch循环开头,避免梯度累积错误,并添加loss监控。

内容的提问来源于stack exchange,提问作者Hero of time

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:42:39