TypeError:“ _ IncompatibleKeys”对象不可调用

时间:2019-11-26 00:16:13

标签: python machine-learning neural-network conv-neural-network

我正在为一个多标签分类问题训练CNN,并用.pt保存了我的torch.save(model.state_dict(), "model.pt")模型。由于某种原因,当我使用自定义函数predict(x)测试模型时,该函数将图像数组作为输入,因此出现以下错误:TypeError: '_IncompatibleKeys' object is not callable。它指出了以下路线的最后一块:y_test_pred = model(images_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()

1 个答案:

答案 0 :(得分:2)

越野车的行是model = model.load_state_dict(torch.load('model.pt'))。根据{{​​3}},load_state_dict返回具有missing_keysunexpected_keys字段的NamedTuple,而不是模型对象。在您的代码中,您将此命名元组分配给model变量,因此,当您在下一行中调用model时,您实际上是在尝试调用NamedTuple,这会给您TypeError。

相反,根据protwo/urls.py,您应该执行以下操作:

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