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

PyTorch加载CNN模型预测报错:TypeError: 'collections.OrderedDict'对象不可调用

解决PyTorch加载模型后调用报错:TypeError: 'collections.OrderedDict' object is not callable

你踩了PyTorch模型保存/加载的一个常见坑——你加载回来的不是完整的模型实例,而是模型的状态字典(state_dict),也就是一个OrderedDict类型的参数集合,直接用它做预测调用自然会报错。

错误原因拆解

如果训练时你用的是torch.save(model.state_dict(), "score_detector.pkl")这种方式保存,那torch.load()拿到的就是模型所有层的参数字典,而非可以直接调用的模型对象。这就像你只有一堆零件,还没拼成能干活的机器,肯定没法直接用。

一步步解决问题

1. 重构你的CNN模型结构

首先要把训练时定义的CNN类原封不动地写出来——层的数量、参数、顺序必须和训练时完全一致,否则参数没法对应上。比如假设你的模型是这样的(请替换成你实际的模型结构):

import torch
import torch.nn as nn
import torch.nn.functional as F

class CNN(nn.Module):
    def __init__(self):
        super().__init__()
        # 和训练时完全一致的层结构
        self.conv1 = nn.Conv2d(1, 16, kernel_size=5, padding=2)
        self.pool = nn.MaxPool2d(2)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=5, padding=2)
        self.fc1 = nn.Linear(32 * 7 * 7, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        # 和训练时完全一致的前向传播逻辑
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(x.size(0), -1)
        fc1_out = F.relu(self.fc1(x))
        output = self.fc2(fc1_out)
        # 对应你原代码返回的test_output和last_layer
        return output, fc1_out

2. 正确加载模型参数

先实例化模型,再把加载的状态字典“注入”到模型中:

# 1. 创建模型实例,并移到GPU(和训练时保持一致)
cnn = CNN().cuda()
# 2. 加载保存的状态字典到模型
cnn.load_state_dict(torch.load("/usr/prakt/w153/Desktop/score_detector.pkl"))
# 3. 必须切换到评估模式!避免BatchNorm、Dropout等层干扰预测结果
cnn.eval()

3. 优化你的预测代码

你的代码里用了Variable和volatile=True,这是PyTorch 0.4之前的旧写法,现在可以简化,同时要保证图像预处理和训练时一致:

import scipy.ndimage

# 读取图像
img = scipy.ndimage.imread("/usr/prakt/w153/Desktop/resize_num_three.png")
# 图像预处理(和训练时对齐):
# 如果是RGB图转灰度图:img = img.mean(axis=2)
# 归一化到0-1范围(MNIST数据的常规处理)
img = img / 255.0
# 调整维度为模型需要的格式:(28,28) → (1,1,28,28),对应[batch_size, channels, height, width]
test_x = torch.FloatTensor(img).unsqueeze(0).unsqueeze(1).cuda()

# 用torch.no_grad()关闭梯度计算,节省内存
with torch.no_grad():
    test_output, last_layer = cnn(test_x)
# 获取最终预测结果
pred = torch.max(test_output, 1)[1].item()
print(f"预测的数字是: {pred}")

额外提醒

  • 如果想在CPU上预测,加载模型时添加map_location='cpu':torch.load("xxx.pkl", map_location='cpu'),同时模型实例不用移到GPU。
  • 注意颜色模式:MNIST是黑底白字,如果你的图像是白底黑字,需要反转:img = 1 - img,否则模型可能识别不准。
  • 确认图像尺寸确实是28*28,和MNIST数据集一致。

内容的提问来源于stack exchange,提问作者Yingqiang Gao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:52