Pytorch运行时错误:期望的标量类型为Float,但是找到了Byte。

14

我正在处理一个典型的数字例子。我想创建我的第一个神经网络,用于预测数字图像{0,1,2,3,4,5,6,7,8,9}的标签。因此,train.txt文件的第一列是标签,所有其他列都是每个标签的特征。我已经定义了一个类来导入我的数据:

class DigitDataset(Dataset):
    """Digit dataset."""

    def __init__(self, file_path, transform=None):
        """
        Args:
            csv_file (string): Path to the csv file with annotations.
            root_dir (string): Directory with all the images.
            transform (callable, optional): Optional transform to be applied
                on a sample.
        """
        self.data = pd.read_csv(file_path, header = None, sep =" ")
        self.transform = transform

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

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        labels = self.data.iloc[idx,0]
        images = self.data.iloc[idx,1:-1].values.astype(np.uint8).reshape((1,16,16))

        if self.transform is not None:
            sample = self.transform(sample)
        return images, labels

然后我运行这些命令将我的数据集分成批次,定义一个模型和损失:

train_dataset = DigitDataset("train.txt")
train_loader = DataLoader(train_dataset, batch_size=64,
                        shuffle=True, num_workers=4)

# Model creation with neural net Sequential model
model=nn.Sequential(nn.Linear(256, 128), # 1 layer:- 256 input 128 o/p
                    nn.ReLU(),          # Defining Regular linear unit as activation
                    nn.Linear(128,64),  # 2 Layer:- 128 Input and 64 O/p
                    nn.Tanh(),          # Defining Regular linear unit as activation
                    nn.Linear(64,10),   # 3 Layer:- 64 Input and 10 O/P as (0-9)
                    nn.LogSoftmax(dim=1) # Defining the log softmax to find the probablities 
for the last output unit 
                  ) 

# defining the negative log-likelihood loss for calculating loss
criterion = nn.NLLLoss()

images, labels = next(iter(train_loader))
images = images.view(images.shape[0], -1)

logps = model(images) #log probabilities
loss = criterion(logps, labels) #calculate the NLL-loss

我承认自己犯了错误:

---------------------------------------------------------------------------
   RuntimeError                              Traceback (most recent call last) 
    <ipython-input-2-7f4160c1f086> in <module>
     47 images = images.view(images.shape[0], -1)
     48 
---> 49 logps = model(images) #log probabilities
     50 loss = criterion(logps, labels) #calculate the NLL-loss

~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self, 
*input, **kwargs)
    725             result = self._slow_forward(*input, **kwargs)
    726         else:
--> 727             result = self.forward(*input, **kwargs)
    728         for hook in itertools.chain(
    729                 _global_forward_hooks.values(),

~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/container.py in forward(self, input)
    115     def forward(self, input):
    116         for module in self:
--> 117             input = module(input)
    118         return input
    119 

~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self, 
*input, **kwargs)
    725             result = self._slow_forward(*input, **kwargs)
    726         else:
--> 727             result = self.forward(*input, **kwargs)
    728         for hook in itertools.chain(
    729                 _global_forward_hooks.values(),

 ~/anaconda3/lib/python3.8/site-packages/torch/nn/modules/linear.py in forward(self, input)
     91 
     92     def forward(self, input: Tensor) -> Tensor:
---> 93         return F.linear(input, self.weight, self.bias)
     94 
     95     def extra_repr(self) -> str:

 ~/anaconda3/lib/python3.8/site-packages/torch/nn/functional.py in linear(input, weight, bias)
   1688     if input.dim() == 2 and bias is not None:
   1689         # fused op is marginally faster
-> 1690         ret = torch.addmm(bias, input, weight.t())
   1691     else:
   1692         output = input.matmul(weight.t())

RuntimeError: expected scalar type Float but found Byte

你知道出了什么问题吗?感谢你的耐心和帮助!

3个回答

20

这一行是导致错误的原因:

images = self.data.iloc[idx, 1:-1].values.astype(np.uint8).reshape((1, 16, 16))

imagesuint8byte)类型,但神经网络需要浮点数作为输入以便计算梯度(使用整数无法进行反向传播的梯度计算,因为整数是不连续且不可微分的)。

您可以使用torchvision.transforms.functional.to_tensor将图像转换为float类型,并转换为[0, 1]范围内的值,如下所示:

import torchvision

images = torchvision.transforms.functional.to_tensor(
    self.data.iloc[idx, 1:-1].values.astype(np.uint8).reshape((1, 16, 16))
)

或者只需除以255即可将值转换为[0, 1]范围内的数值。


它可以工作,但是现在我有一个损失函数的问题,并且我无法将“torchvision.transforms.functional.to_tensor”应用于“标签”,因为它们不是图像。实际上,我会遇到这个错误:RuntimeError: expected scalar type Long but found Double - CyberMathIdiot
通过 your_tensor.float() 将其转换为 float - Szymon Maszke
我写了labels = torch.from_numpy(np.array(self.data.iloc[idx,0])).float()但是我一直收到一个错误信息RuntimeError: expected scalar type Long but found Float我也尝试过 labels.float(),但它没有起作用。 - CyberMathIdiot
1
好的,我通过labels = torch.from_numpy(np.array(self.data.iloc[idx,0])).long()解决了它。非常感谢您的帮助! - CyberMathIdiot

4

这里有一个简单的解决方案。

只需将.float()添加到图像张量中即可。像这样:

# Forward Pass
outputs = model(images.float())

1
import torch
import torchvision
import matplotlib.pyplot as plt
from time import time
from torchvision import datasets, transforms
from torch import nn, optim

transform = transforms.Compose([transforms.ToTensor(),
                              transforms.Normalize((0.5,), (0.5,)),
                              ])

trainset = datasets.MNIST('data/train', download=True, train=True, transform=transform)
valset = datasets.MNIST('data/test', download=True, train=False, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
valloader = torch.utils.data.DataLoader(valset, batch_size=64, shuffle=True)



input_size = 784
hidden_sizes = [128,128,64]
output_size = 10

model = nn.Sequential(nn.Linear(input_size, hidden_sizes[0]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[0], hidden_sizes[1]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[1], hidden_sizes[2]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[2], output_size),
                      nn.LogSoftmax(dim=1))
# print(model)

criterion = nn.NLLLoss()
images, labels = next(iter(trainloader))
images = images.view(images.shape[0], -1)

logps = model(images) #log probabilities
loss = criterion(logps, labels) #calculate the NLL loss




optimizer = optim.SGD(model.parameters(), lr=0.003, momentum=0.9)
time0 = time()
epochs = 15
for e in range(epochs):
    running_loss = 0
    for images, labels in trainloader:
        # Flatten MNIST images into a 784 long vector
        images = images.view(images.shape[0], -1)
    
        # Training pass
        optimizer.zero_grad()
        
        output = model(images)
        loss = criterion(output, labels)
        
        #This is where the model learns by backpropagating
        loss.backward()
        
        #And optimizes its weights here
        optimizer.step()
        
        running_loss += loss.item()
    else:
        print("Epoch {} - Training loss: {}".format(e, running_loss/len(trainloader)))
    print("\nTraining Time (in minutes) =",(time()-time0)/60)
    
    
    
    
    
images, labels = next(iter(valloader))
img = images[0].view(1, 784)
with torch.no_grad():
    logps = model(img)

ps = torch.exp(logps)
probab = list(ps.numpy()[0])
print("Predicted Digit =", probab.index(max(probab)))
# view_classify(img.view(1, 28, 28), ps)





correct_count, all_count = 0, 0
for images,labels in valloader:
  for i in range(len(labels)):
    img = images[i].view(1, 784)
    with torch.no_grad():
        logps = model(img)

    
    ps = torch.exp(logps)
    probab = list(ps.numpy()[0])
    pred_label = probab.index(max(probab))
    true_label = labels.numpy()[i]
    if(true_label == pred_label):
      correct_count += 1
    all_count += 1

print("Number Of Images Tested =", all_count)
print("\nModel Accuracy =", (correct_count/all_count))


torch.save(model, './my_mnist_model.pt') ```

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接