Python 如何在pytorch中测试一个图像

Python 如何在pytorch中测试一个图像,python,machine-learning,deep-learning,pytorch,Python,Machine Learning,Deep Learning,Pytorch,我在pytorch中创建了我的模型,并且工作得非常好,但是当我只想测试一个图像时batch_size=1总是返回第二个类(在本例中是一只狗) 我尝试使用batch>1进行测试,在所有情况下都可以 架构: model = models.densenet121(pretrained=True) for param in model.parameters(): param.requires_grad = False from collections import OrderedDict classi

我在pytorch中创建了我的模型,并且工作得非常好,但是当我只想测试一个图像时batch_size=1总是返回第二个类(在本例中是一只狗)

我尝试使用batch>1进行测试,在所有情况下都可以

架构:

model = models.densenet121(pretrained=True)

for param in model.parameters():
param.requires_grad = False
from collections import OrderedDict
classifier = nn.Sequential(OrderedDict([
                          ('fc1', nn.Linear(1024, 500)),
                          ('relu', nn.ReLU()),
                          ('fc2', nn.Linear(500, 2)),
                          ('output', nn.LogSoftmax(dim=1))
                          ]))

model.classifier = classifier
所以我的张量是[batch,3224,224]

我试过:

resize
reshape
unsqueeze(0)
当是一个图像时,响应总是[[0.4741,0.5259]]

我的测试代码

from PIL import *
msize = 256
loader = transforms.Compose([transforms.Scale(imsize), transforms.ToTensor()])

def image_loader(image_name):
    """load image, returns cuda tensor"""
    image = Image.open(image_name)
    image = loader(image).float()
    image = image.unsqueeze(0) 
    return image.cuda()
image = image_loader('Cat_Dog_data/test/cat/cat.16.jpg') 
with torch.no_grad():
    logits = model.forward(image)
ps = torch.exp(logits)
_, predTest = torch.max(ps,1)
print(ps) ## same value in all cases
imagen_mostrar = images[ii].to('cpu') 
helper.imshow(imagen_mostrar,title=clas_perro_gato(predTest), normalize=True)
andrea_data = datasets.ImageFolder(data_dir + '/andrea', transform=test_transforms)
andrealoader = torch.utils.data.DataLoader(andrea_data, batch_size=1, shuffle=True)
dataiter = iter(andrealoader)
images, labels = dataiter.next()
images, labels = images.to(device), labels.to(device)
ps = torch.exp(model.forward(images))
_, predTest = torch.max(ps,1) 
print(ps.float())
第二个测试代码

from PIL import *
msize = 256
loader = transforms.Compose([transforms.Scale(imsize), transforms.ToTensor()])

def image_loader(image_name):
    """load image, returns cuda tensor"""
    image = Image.open(image_name)
    image = loader(image).float()
    image = image.unsqueeze(0) 
    return image.cuda()
image = image_loader('Cat_Dog_data/test/cat/cat.16.jpg') 
with torch.no_grad():
    logits = model.forward(image)
ps = torch.exp(logits)
_, predTest = torch.max(ps,1)
print(ps) ## same value in all cases
imagen_mostrar = images[ii].to('cpu') 
helper.imshow(imagen_mostrar,title=clas_perro_gato(predTest), normalize=True)
andrea_data = datasets.ImageFolder(data_dir + '/andrea', transform=test_transforms)
andrealoader = torch.utils.data.DataLoader(andrea_data, batch_size=1, shuffle=True)
dataiter = iter(andrealoader)
images, labels = dataiter.next()
images, labels = images.to(device), labels.to(device)
ps = torch.exp(model.forward(images))
_, predTest = torch.max(ps,1) 
print(ps.float())
例如,如果我将批次大小更改为1,则始终返回一个张量,表示这是一只狗[0.43,0.57]

谢谢

如果您的模型是“正确的”,它只是预测了一只狗,那么您可以使用
torch.argmax(output,dim=1)
获得标签,无论批的大小如何

无论如何,您不应该使用
LogSoftmax
作为激活,请使用作为丢失函数,并从最后一层中删除激活,并且仅输出一个神经元(图像仅为狗的概率)。在您的案例中,它看起来是这样的:

classifier = nn.Sequential(
    OrderedDict(
        [
            ("fc1", nn.Linear(1024, 500)),
            ("relu", nn.ReLU()),
            ("fc2", nn.Linear(500, 1)),
            # See? No activation needed
        ]
    )
)

只需运行
output>0
+您就可以通过上述网络获得正确的标签,您可以“免费”获得数值稳定性。

我意识到我的模型没有处于eval模式


因此,我刚刚添加了model.eval(),就这样,适用于任何大小的批处理

请发布代码,在其中运行批处理>1和批处理==1的eval。好的,我现在就这样做了!无法看到批次>1的评估结果第二类是狗,但第一类是猫,模型必须在两者之间进行选择,当我使用Softmax函数时,如果没有此函数,返回一个具有2个值的张量(概率),我必须如何正确使用?因为BCEWithLogitsLoss问我一个张量[64],所以我得到了错误值error:目标大小(torch.size([64])必须与输入大小(torch.size([64,1])相同,所以不需要第一类,因为如果网络的输出小于零,它将被标记为一。大于此值的任何内容都将被归类为
。要修复错误,您必须使用
input.flatte()
对输入进行
展平,使其与目标匹配(或通过
target.unsqueze(dim=1)
目标进行unsqueze
)。您使用的是什么版本的PyTorch?PyTorch V.1.1.0,好的,没有显示错误,但当我培训我的型号时,acc没有增加,我的代码: