用sklearn.metrics.accuracy_score计算pytorch模型准确率前,必须对logits调用torch.argmax(dim=1)获取整数预测标签,并确保y_true和y_pred均为cpu上的1d int/long型数组或numpy.ndarray,且模型处于eval()模式、推理过程置于torch.no_grad()内。

用 sklearn.metrics.accuracy_score 计算 PyTorch 模型准确率,必须先取 argmax
PyTorch 分类模型输出的是 logits(未归一化的分数),不是概率或类别标签。直接喂给 accuracy_score(y_true, y_pred) 会报错或结果错误——因为 y_pred 是 float 张量,而 accuracy_score 要求整数类标。
正确做法是:在 torch.no_grad() 下前向传播,然后对 logits 用 torch.argmax(..., dim=1) 提取预测类别索引。
- 别用
torch.softmax(logits, dim=1).argmax(...)—— softmax 不必要,且可能引入数值误差 - 确保
y_true和y_pred都是 CPU 上的 1Dtorch.Tensor或numpy.ndarray,类型为long或int - 如果数据在 GPU 上,记得调用
.cpu()再转.numpy(),否则sklearn会报错
torch.no_grad() 必须包裹整个推理过程,不能只包 model() 调用
只写 with torch.no_grad(): output = model(x) 是不够的——如果你后续还做了 output.argmax(1) 或其他计算,这些操作本身不参与梯度计算,但没加 no_grad 不影响正确性;真正要防的是意外触发梯度累积(比如模型还在 training 模式下、或用了某些带梯度的后处理)。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
更稳妥的做法是把数据加载、前向、取 argmax、移入 CPU 全部包进 torch.no_grad() 块里:
with torch.no_grad():
for x, y in val_loader:
x, y = x.to(device), y.to(device)
logits = model(x)
preds = logits.argmax(dim=1)
y_list.append(y.cpu().numpy())
pred_list.append(preds.cpu().numpy())
- 漏掉
.cpu()直接传给accuracy_score会触发TypeError: can't convert CUDA tensor to numpy - 如果模型处于
model.train()模式(比如忘了调model.eval()),BatchNorm / Dropout 可能导致评估结果不稳定
多分类 vs 二分类:accuracy_score 行为一致,但别和 f1_score 混用参数
accuracy_score 对二分类和多分类完全透明——它只比对两个整数序列是否逐位相等。但容易踩坑的是,有人顺手把同一套代码改成用 f1_score,却忘了 average 参数默认是 'binary',在多分类时必须显式设为 'macro' 或 'weighted',否则报错。
- 二分类下:
accuracy_score(y_true, y_pred)和f1_score(y_true, y_pred, average='binary')都合法 - 多分类下:
f1_score(y_true, y_pred, average='macro')才安全;不设average会抛ValueError: Target is multiclass but average='binary' - 如果标签是字符串(如
['cat', 'dog']),必须先用LabelEncoder数字化,accuracy_score不接受非数值标签
批量太大时内存爆掉?别一次性 collect 全部 preds 和 labels
在验证集很大时,把所有 y_list 和 pred_list 存成 list 再拼成大 array,容易 OOM。更省内存的做法是边跑边累加正确样本数:
correct = 0
total = 0
with torch.no_grad():
for x, y in val_loader:
x, y = x.to(device), y.to(device)
preds = model(x).argmax(dim=1)
correct += preds.eq(y).sum().item()
total += y.size(0)
acc = correct / total
- 这个写法不依赖
sklearn,也避免了 CPU/GPU 数据搬运开销 - 但注意:它只给整体准确率,没法算 per-class recall/precision —— 如果需要细粒度指标,还是得 collect 全量预测结果
- 用
preds.eq(y).sum().item()而不是(preds == y).sum().item(),前者是 PyTorch 推荐写法,语义更明确
model.eval() 和 torch.no_grad() 的配合使用——少一个,评估指标就可能漂移;collect 结果时忘掉 .cpu(),程序当场停在 sklearn 的类型检查上。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










