ValueError:只有一个元素张量可以转换为Python标量



我正在学习本教程。

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

我在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个划时代来训练我的模型,而不是像教程中那样使用35个划时代,不确定这是否与此有关。除此之外,我还不知道这可能是什么?我还在train_dataset的选项中删除了normalize=False,因为它一直给我一个错误,我读到它可以删除,但我不太确定?

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

最新更新