【问题标题】:ValueError: only one element tensors can be converted to Python scalarsValueError:只有一个元素张量可以转换为 Python 标量
【发布时间】:2020-11-08 17:06:16
【问题描述】:

我正在关注this tutorial

我在最后一部分,我们在回归中组合模型。

我在 jupyter 中编码如下:

import shutil
import os
import time
from datetime import datetime
import argparse
import pandas
import numpy as np
from tqdm import tqdm
from tqdm import tqdm_notebook

import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
from torchsample.transforms import RandomRotate, RandomTranslate, RandomFlip, ToTensor, Compose, RandomAffine
from torchvision import transforms
import torch.nn.functional as F
from tensorboardX import SummaryWriter

import dataloader
from dataloader import MRDataset
import model

from sklearn import metrics

def extract_predictions(task, plane, train=True):
    assert task in ['acl', 'meniscus', 'abnormal']
    assert plane in ['axial', 'coronal', 'sagittal']
    
    models = os.listdir('models/')

    model_name = list(filter(lambda name: task in name and plane in name, models))[0]
    model_path = f'models/{model_name}'

    mrnet = torch.load(model_path)
    _ = mrnet.eval()
    
    train_dataset = MRDataset('data/', 
                              task, 
                              plane, 
                              transform=None, 
                              train=train, 
                              )
    
    train_loader = torch.utils.data.DataLoader(train_dataset, 
                                               batch_size=1, 
                                               shuffle=False, 
                                               num_workers=10, 
                                               drop_last=False)
    predictions = []
    labels = []
    with torch.no_grad():
        for image, label, _ in tqdm_notebook(train_loader):
            logit = mrnet(image.cuda())
            prediction = torch.sigmoid(logit)
            predictions.append(prediction.item())
            labels.append(label.item())

    return predictions, labels

task = 'acl'
results = {}

for plane in ['axial', 'coronal', 'sagittal']:
    predictions, labels = extract_predictions(task, plane)
    results['labels'] = labels
    results[plane] = predictions
    
X = np.zeros((len(predictions), 3))
X[:, 0] = results['axial']
X[:, 1] = results['coronal']
X[:, 2] = results['sagittal']

y = np.array(labels)

logreg = LogisticRegression(solver='lbfgs')
logreg.fit(X, y)

task = 'acl'
results_val = {}

for plane in ['axial', 'coronal', 'sagittal']:
    predictions, labels = extract_predictions(task, plane, train=False)
    results_val['labels'] = labels
    results_val[plane] = predictions

y_pred = logreg.predict_proba(X_val)[:, 1]
metrics.roc_auc_score(y_val, y_pred)

但是我得到了这个错误:

ValueError                                Traceback (most recent call last)
<ipython-input-2-979acb314bc5> in <module>
      3 
      4 for plane in ['axial', 'coronal', 'sagittal']:
----> 5     predictions, labels = extract_predictions(task, plane)
      6     results['labels'] = labels
      7     results[plane] = predictions

<ipython-input-1-647731b6b5c8> in extract_predictions(task, plane, train)
     54             logit = mrnet(image.cuda())
     55             prediction = torch.sigmoid(logit)
---> 56             predictions.append(prediction.item())
     57             labels.append(label.item())
     58 

ValueError: only one element tensors can be converted to Python scalars

这是 MRDataset 代码以防万一:

class MRDataset(data.Dataset):
    def __init__(self, root_dir, task, plane, train=True, transform=None, weights=None):
        super().__init__()
        self.task = task
        self.plane = plane
        self.root_dir = root_dir
        self.train = train
        if self.train:
            self.folder_path = self.root_dir + 'train/{0}/'.format(plane)
            self.records = pd.read_csv(
                self.root_dir + 'train-{0}.csv'.format(task), header=None, names=['id', 'label'])
        else:
            transform = None
            self.folder_path = self.root_dir + 'valid/{0}/'.format(plane)
            self.records = pd.read_csv(
                self.root_dir + 'valid-{0}.csv'.format(task), header=None, names=['id', 'label'])

        self.records['id'] = self.records['id'].map(
            lambda i: '0' * (4 - len(str(i))) + str(i))
        self.paths = [self.folder_path + filename +
                      '.npy' for filename in self.records['id'].tolist()]
        self.labels = self.records['label'].tolist()

        self.transform = transform
        if weights is None:
            pos = np.sum(self.labels)
            neg = len(self.labels) - pos
            self.weights = torch.FloatTensor([1, neg / pos])
        else:
            self.weights = torch.FloatTensor(weights)

    def __len__(self):
        return len(self.paths)

    def __getitem__(self, index):
        array = np.load(self.paths[index])
        label = self.labels[index]
        if label == 1:
            label = torch.FloatTensor([[0, 1]])
        elif label == 0:
            label = torch.FloatTensor([[1, 0]])

        if self.transform:
            array = self.transform(array)
        else:
            array = np.stack((array,)*3, axis=1)
            array = torch.FloatTensor(array)

        # if label.item() == 1:
        #     weight = np.array([self.weights[1]])
        #     weight = torch.FloatTensor(weight)
        # else:
        #     weight = np.array([self.weights[0]])
        #     weight = torch.FloatTensor(weight)

        return array, label, self.weights

我只对 MRI 的每个平面使用 1 和 2 个 epoch 训练我的模型,而不是教程中的 35 个,不确定这是否与此有关。除此之外,我对这可能是什么感到困惑?我还在train_dataset 的选项中删除了normalize=False,因为它一直给我一个错误,我读到它可以被删除,但我不太确定?

【问题讨论】:

    标签: python python-3.x deep-learning pytorch


    【解决方案1】:

    只有包含单个值的张量可以用item() 转换为标量,尝试打印prediction 的内容,我想这是一个概率向量,指示哪个标签最有可能。在prediction 上使用argmax 将为您提供实际预测的标签(假设您的标签是0-n)。

    【讨论】:

    • print(prediction) 只是说它没有定义? np.argmax(预测)同样如此。与预测相同
    • 你需要把它放在定义prediction的for循环中。此外,使用 torch.argmax,因为您使用的是 torch 张量而不是 np 数组。
    • 对于 tqdm_notebook(train_loader) 中的图像、标签、_: logit = mrnet(image.cuda()) torch.argmax(predictions) prediction = torch.sigmoid(logit) predictions.append(prediction. item()) labels.append(label.item()) print(predictions) return predictions, labels Returns TypeError: argmax(): argument 'input' (position 1) must be Tensor, not list 也许我理解不正确
    • argmax 应该用于prediction 而不是predictions...torch.argmax(prediction)。请重新阅读我的答案...
    猜你喜欢
    • 2021-03-16
    • 2019-02-04
    • 2022-01-12
    • 2021-07-23
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 2022-01-19
    • 2021-03-04
    相关资源
    最近更新 更多