Python 类型错误:'_不兼容密钥';对象不可调用

Python 类型错误:'_不兼容密钥';对象不可调用,python,machine-learning,neural-network,conv-neural-network,Python,Machine Learning,Neural Network,Conv Neural Network,我正在培训CNN解决多标签分类问题,并已将我的.pt模型保存为torch.save(model.state\u dict(),“model.pt”)。由于某种原因,当我使用一个自定义函数predict(x)测试模型时,我得到了以下错误:TypeError:“\u compatibleKeys”对象不可调用。它指出了下面cade的最后一部分:y\u test\u pred=model(images\u tensors)。你知道这里的问题是什么吗 import numpy as np import

我正在培训CNN解决多标签分类问题,并已将我的
.pt
模型保存为
torch.save(model.state\u dict(),“model.pt”)
。由于某种原因,当我使用一个自定义函数
predict(x)
测试模型时,我得到了以下错误:
TypeError:“\u compatibleKeys”对象不可调用
。它指出了下面cade的最后一部分:
y\u test\u pred=model(images\u tensors)
。你知道这里的问题是什么吗

import numpy as np
import cv2
import torch
from torch import nn
import torch.nn.functional as F
import os


class Net(nn.Module):
    def __init__(self, classes_number):
        super().__init__()
        self.ConvLayer1 = nn.Sequential(
            nn.Conv2d(1, 8, 5),  # inp (1, 512, 512)
            nn.MaxPool2d(2),
            nn.ReLU()  # op (8, 254, 254)
        )
        self.ConvLayer2 = nn.Sequential(
            nn.Conv2d(8, 16, 3),  # inp (8, 254, 254)
            nn.MaxPool2d(2),
            nn.ReLU(),
            nn.BatchNorm2d(16)  # op (16, 126, 126)
        )
        self.ConvLayer3 = nn.Sequential(
            nn.Conv2d(16, 32, 3),  # inp (16, 126, 126)
            nn.MaxPool2d(2),
            nn.ReLU(),
            nn.BatchNorm2d(32)  # op (32, 62, 62)
        )
        self.ConvLayer4 = nn.Sequential(
            nn.Conv2d(32, 64, 3),  # inp (32, 62, 62)
            nn.MaxPool2d(2),
            nn.ReLU()  # op (64, 30, 30)
        )
        self.Lin1 = nn.Linear(30 * 30 * 64, 1500)
        self.drop = nn.Dropout(0.5)
        self.Lin2 = nn.Linear(1500, 150)
        self.drop = nn.Dropout(0.3)
        self.Lin3 = nn.Linear(150, classes_number)

    def forward(self, x):
        x = self.ConvLayer1(x)
        x = self.ConvLayer2(x)
        x = self.ConvLayer3(x)
        x = self.ConvLayer4(x)
        x = x.view(x.size(0), -1)
        x = F.relu(self.Lin1(x))
        x = self.drop(x)
        x = F.relu(self.Lin2(x))
        x = self.drop(x)
        x = self.Lin3(x)
        out = torch.sigmoid(x)
        return out


def predict(x):
    # On the exam, x will be a list of all the paths to the images of our held-out set
    images = []
    for img_path in x:
        img = cv2.imread(img_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # Turn into greyscale
        img = cv2.resize(img, (512, 512))
        images.append(img)
    images = np.array(images)
    images = images.reshape(len(images), 1, images.shape[1], images.shape[1])  # converting(n,512,512)>(n,1,512,512)
    images_tensors = torch.FloatTensor(np.array(images))
    images_tensors = images_tensors.to(device)
    classes = ["red blood cell", "difficult", "gametocyte", "trophozoite", "ring", "schizont", "leukocyte"]
    model = Net(len(classes))
    model = model.load_state_dict(torch.load('model.pt'))


    y_test_pred = model(images_tensors)
    y_test_pred[y_test_pred > 0.49] = 1
    y_test_pred[y_test_pred < 0.5] = 0

    return y_test_pred.cpu().detach()
将numpy导入为np
进口cv2
进口火炬
从火炬进口
导入torch.nn.功能为F
导入操作系统
类别网络(nn.模块):
定义初始(自身、类别编号):
super()。\uuuu init\uuuuu()
self.ConvLayer1=nn.Sequential(
nn.Conv2d(1,8,5),#inp(1512512)
nn.MaxPool2d(2),
nn.ReLU()#op(8254254)
)
self.ConvLayer2=nn.Sequential(
nn.Conv2d(8,16,3),#inp(8254254)
nn.MaxPool2d(2),
nn.ReLU(),
nn.2D(16)#op(16、126、126)
)
self.ConvLayer3=nn.Sequential(
nn.Conv2d(16,32,3),#inp(16,126,126)
nn.MaxPool2d(2),
nn.ReLU(),
nn.2D(32)#op(32、62、62)
)
self.ConvLayer4=nn.Sequential(
nn.Conv2d(32,64,3),#inp(32,62,62)
nn.MaxPool2d(2),
nn.ReLU()#op(64,30,30)
)
self.Lin1=nn.Linear(30*30*641500)
self.drop=nn.drop(0.5)
self.Lin2=nn.Linear(1500150)
self.drop=nn.drop(0.3)
self.Lin3=nn.Linear(150,类数)
def前进(自身,x):
x=自。ConvLayer1(x)
x=自。ConvLayer2(x)
x=self.ConvLayer3(x)
x=self.ConvLayer4(x)
x=x.view(x.size(0),-1)
x=F.relu(自Lin1(x))
x=自投(x)
x=F.relu(自Lin2(x))
x=自投(x)
x=自Lin3(x)
out=火炬。乙状结肠(x)
返回
def预测(x):
#在考试中,x将是一个列表,列出所有指向我们所持场景图像的路径
图像=[]
对于x中的img_路径:
img=cv2.imread(img\u路径)
img=cv2.cvt颜色(img,cv2.COLOR_bgr2灰色)#变为灰度
img=cv2。调整大小(img,(512,512))
images.append(img)
images=np.array(图像)
images=images.reformate(len(images),1,images.shape[1],images.shape[1])#转换(n,512512)>(n,1512512)
images\u张量=torch.FloatTensor(np.array(images))
images\u tensors=images\u tensors.to(设备)
类别=[“红细胞”、“难培养”、“配子体”、“滋养体”、“环”、“裂殖体”、“白细胞”]
模型=净(len(类))
model=model.load\u state\u dict(torch.load('model.pt'))
y_test_pred=模型(图像张量)
y_-test_-pred[y_-test_-pred>0.49]=1
y_测试_pred[y_测试_pred<0.5]=0
返回y_test_pred.cpu().detach()

小车线路是
model=model.load\u state\u dict(torch.load('model.pt'))
。根据,load_state_dict返回一个包含
缺少\u键
意外\u键
字段的命名元组,而不是一个模型对象。在代码中,您将此命名元组分配给
model
变量,因此,当您在下一行中调用
model
时,实际上是在尝试调用NamedTuple,这会导致TypeError

相反,根据该计划,您应该做如下操作:

model = Net(len(classes))
model.load_state_dict(torch.load(PATH))
model.eval()