【问题标题】:Training Error in PyTorch - RuntimeError: Expected object of type FloatTensor vs ByteTensorPyTorch 中的训练错误 - RuntimeError:FloatTensor 与 ByteTensor 类型的预期对象
【发布时间】:2018-11-28 12:42:18
【问题描述】:

一个最小的工作示例很难在这里发布,但基本上我正在尝试修改这个项目http://torch.ch/blog/2015/09/21/rmva.html,它可以与 MNIST 顺利配合。我正在尝试使用我自己的数据集和自定义 dataloader.py 来运行它,如下所示:

from __future__ import print_function, division #ds
import numpy as np
from utils import plot_images

import os #ds
import pandas as pd #ds
from skimage import io, transform #ds
import torch
from torchvision import datasets
from torch.utils.data import Dataset, DataLoader #ds
from torchvision import transforms
from torchvision import utils #ds
from torch.utils.data.sampler import SubsetRandomSampler


class CDataset(Dataset):


    def __init__(self, csv_file, root_dir, 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.frame = pd.read_csv(csv_file)
        self.root_dir = root_dir
        self.transform = transform

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

    def __getitem__(self, idx):
        img_name = os.path.join(self.root_dir,
                                self.frame.iloc[idx, 0]+'.jpg')
        image = io.imread(img_name)
#       image = image.transpose((2, 0, 1))
        labels = np.array(self.frame.iloc[idx, 1])#.as_matrix() #ds
        #landmarks = landmarks.astype('float').reshape(-1, 2)
        #print(image.shape)
        #print(img_name,labels)
        sample = {'image': image, 'labels': labels}

        if self.transform:
            sample = self.transform(sample)

        return sample

class ToTensor(object):
    """Convert ndarrays in sample to Tensors."""


    def __call__(self, sample):
        image, labels = sample['image'], sample['labels']
        #print(image)
        #print(labels)
        # swap color axis because
        # numpy image: H x W x C
        # torch image: C X H X W
        image = image.transpose((2, 0, 1))
        #print(image.shape)
        #print((torch.from_numpy(image)))
        #print((torch.from_numpy(labels)))
        return {'image': torch.from_numpy(image),
                'labels': torch.from_numpy(labels)}


def get_train_valid_loader(data_dir,
                           batch_size,
                           random_seed,
                           #valid_size=0.1, #ds
                           #shuffle=True,
                           show_sample=False,
                           num_workers=4,
                           pin_memory=False):
    """
    Utility function for loading and returning train and valid
    multi-process iterators over the MNIST dataset. A sample
    9x9 grid of the images can be optionally displayed.

    If using CUDA, num_workers should be set to 1 and pin_memory to True.

    Args
    ----
    - data_dir: path directory to the dataset.
    - batch_size: how many samples per batch to load.
    - random_seed: fix seed for reproducibility.
    - #ds valid_size: percentage split of the training set used for
      the validation set. Should be a float in the range [0, 1].
      In the paper, this number is set to 0.1.
    - shuffle: whether to shuffle the train/validation indices.
    - show_sample: plot 9x9 sample grid of the dataset.
    - num_workers: number of subprocesses to use when loading the dataset.
    - pin_memory: whether to copy tensors into CUDA pinned memory. Set it to
      True if using GPU.

    Returns
    -------
    - train_loader: training set iterator.
    - valid_loader: validation set iterator.
    """
    #ds
    #error_msg = "[!] valid_size should be in the range [0, 1]."
    #assert ((valid_size >= 0) and (valid_size <= 1)), error_msg
    #ds

    # define transforms
    #normalize = transforms.Normalize((0.1307,), (0.3081,))
    trans = transforms.Compose([
        ToTensor(), #normalize,
    ])

    # load train dataset
    #train_dataset = datasets.MNIST(
    #    data_dir, train=True, download=True, transform=trans
    #)


    train_dataset = CDataset(csv_file='/home/Desktop/6June17/util/train.csv',
                                    root_dir='/home/caffe/data/images/',transform=trans)

    # load validation dataset
    #valid_dataset = datasets.MNIST( #ds
    #    data_dir, train=True, download=True, transform=trans #ds
    #)

    valid_dataset = CDataset(csv_file='/home/Desktop/6June17/util/eval.csv',
                                    root_dir='/home/caffe/data/images/',transform=trans)

    num_train = len(train_dataset) 
    train_indices = list(range(num_train)) 
    #ds split = int(np.floor(valid_size * num_train))

    num_valid = len(valid_dataset) #ds
    valid_indices = list(range(num_valid)) #ds

    #if shuffle:
    #    np.random.seed(random_seed)
    #    np.random.shuffle(indices)

    #ds train_idx, valid_idx = indices[split:], indices[:split]
    train_idx = train_indices #ds
    valid_idx = valid_indices #ds

    train_sampler = SubsetRandomSampler(train_idx)
    valid_sampler = SubsetRandomSampler(valid_idx)

    train_loader = torch.utils.data.DataLoader(
        train_dataset, batch_size=batch_size, sampler=train_sampler,
        num_workers=num_workers, pin_memory=pin_memory,
    )

    print(train_loader)

    valid_loader = torch.utils.data.DataLoader(
        valid_dataset, batch_size=batch_size, sampler=valid_sampler,
        num_workers=num_workers, pin_memory=pin_memory,
    )

    # visualize some images
    if show_sample:
        sample_loader = torch.utils.data.DataLoader(
            dataset, batch_size=9, #shuffle=shuffle,
            num_workers=num_workers, pin_memory=pin_memory
        )
        data_iter = iter(sample_loader)
        images, labels = data_iter.next()
        X = images.numpy()
        X = np.transpose(X, [0, 2, 3, 1])
        plot_images(X, labels)

    return (train_loader, valid_loader)


def get_test_loader(data_dir,
                    batch_size,
                    num_workers=4,
                    pin_memory=False):
    """
    Utility function for loading and returning a multi-process
    test iterator over the MNIST dataset.

    If using CUDA, num_workers should be set to 1 and pin_memory to True.

    Args
    ----
    - data_dir: path directory to the dataset.
    - batch_size: how many samples per batch to load.
    - num_workers: number of subprocesses to use when loading the dataset.
    - pin_memory: whether to copy tensors into CUDA pinned memory. Set it to
      True if using GPU.

    Returns
    -------
    - data_loader: test set iterator.
    """
    # define transforms
    #normalize = transforms.Normalize((0.1307,), (0.3081,))
    trans = transforms.Compose([
        ToTensor(), #normalize,
    ])

    # load dataset
    #dataset = datasets.MNIST(
    #    data_dir, train=False, download=True, transform=trans
    #)

    test_dataset = CDataset(csv_file='/home/Desktop/6June17/util/test.csv',
                                    root_dir='/home/caffe/data/images/',transform=trans)

    test_loader = torch.utils.data.DataLoader(
        test_dataset, batch_size=batch_size, shuffle=False,
        num_workers=num_workers, pin_memory=pin_memory,
    )

    return test_loader


#for i_batch, sample_batched in enumerate(dataloader):
#    print(i_batch, sample_batched['image'].size(),
#          sample_batched['landmarks'].size())

#    # observe 4th batch and stop.
#    if i_batch == 3:
#        plt.figure()
#        show_landmarks_batch(sample_batched)
#        plt.axis('off')
#        plt.ioff()
#        plt.show()
#        break

我所做的其他主要更改是关闭验证大小和改组的参数输入(因为我使用的是预先存在的训练、验证和测试拆分,并且我已经改组了这些拆分)

我最后一次更改是在train_one_epoch(self, epoch) 函数中,同时在trainer.py 中进行迭代。我更改了这部分,因为以前 x、y 是作为 "image" 和 "labels" 的字符串返回的 - python 字典的标题而不是批量的值。

for i, batch in enumerate(self.train_loader):
     x, y = batch["image"], batch["labels"]  

但现在我在网络训练中遇到错误,因为我是 pytorch 的新手,所以我无法弄清楚:

[*] Train on 64034 samples, validate on 18951 samples Epoch: 1/200 - LR: 0.000300 <torch.utils.data.dataloader.DataLoader object at 0x7fe065fd4f60>   0%|                                                  | 0/64034 [00:00<?, ?it/s]/home/duygu/recurrent-visual-attention-master/modules.py:106: UserWarning: invalid index of a 0-dim tensor. This will be an error in PyTorch 0.5. Use tensor.item() to convert a 0-dim tensor to a Python number   from_x, to_x = from_x.data[0], to_x.data[0] /home/duygu/recurrent-visual-attention-master/modules.py:107: UserWarning: invalid index of a 0-dim tensor. This will be an error in PyTorch 0.5. Use tensor.item() to convert a 0-dim tensor to a Python number   from_y, to_y = from_y.data[0], to_y.data[0]

Traceback (most recent call last):   File "main.py", line 49, in <module>
    main(config)   File "main.py", line 40, in main
    trainer.train()   File "/home/duygu/recurrent-visual-attention-master/trainer.py", line 168, in train
    train_loss, train_acc = self.train_one_epoch(epoch)   File "/home/duygu/recurrent-visual-attention-master/trainer.py", line 252, in train_one_epoch
    h_t, l_t, b_t, p = self.model(x, l_t, h_t)   File "/usr/local/lib/python3.5/dist-packages/torch/nn/modules/module.py", line 491, in __call__
    result = self.forward(*input, **kwargs)   File "/home/duygu/recurrent-visual-attention-master/model.py", line 101, in forward
    g_t = self.sensor(x, l_t_prev)   File "/usr/local/lib/python3.5/dist-packages/torch/nn/modules/module.py", line 491, in __call__
    result = self.forward(*input, **kwargs)   File "/home/duygu/recurrent-visual-attention-master/modules.py", line 214, in forward
    phi_out = F.relu(self.fc1(phi))   File "/usr/local/lib/python3.5/dist-packages/torch/nn/modules/module.py", line 491, in __call__
    result = self.forward(*input, **kwargs)   File "/usr/local/lib/python3.5/dist-packages/torch/nn/modules/linear.py", line 55, in forward
    return F.linear(input, self.weight, self.bias)   File "/usr/local/lib/python3.5/dist-packages/torch/nn/functional.py", line 992, in linear
    return torch.addmm(bias, input, weight.t()) RuntimeError: Expected object of type torch.FloatTensor but found type torch.ByteTensor for argument #4 'mat1'

我正在寻求有关如何修复此错误并了解导致它的原因的建议。即使在没有 GPU 支持的情况下运行它时,我也会收到此错误。我想知道通过查看初始警告是否以某种方式将我的参数传递为空。

【问题讨论】:

    标签: python image pytorch tensor convolutional-neural-network


    【解决方案1】:

    据我所知,当您评论应用于您的数据集的normalize / transforms.Normalize 操作时,您的图像的值在[0, 1] 之间没有标准化为float,而是而是将它们的 byte 值保持在 [0, 255] 之间。

    尝试应用数据标准化或至少将您的图像转换为float(32 位,而不是 64)值(例如,在ToTensor 中,添加image = image.float() 或者当它仍然是一个numpy 数组时使用data.astype(numpy.float32))在将它们馈送到您的网络之前。

    【讨论】:

    • 嘿,感谢您注意到这一点。真的很有帮助!由于我的数据的性质(或至少不减去平均值),我不喜欢标准化。在 ToTensor 中(或在我读取图像之后)我使用 image = image.astype(float) 投射类型 - 因为它是一个 numpy 数组 - 但这次我得到 RuntimeError: Expected object of type torch.FloatTensor but found type torch .DoubleTensor for argument #4 'mat1' 我想看看为什么
    • 我不知道您的张量 mat1 是如何定义的/分配了哪些数据,但您可以尝试将 mat1 重新定义为 torch.DoubleTensor 或转换数据,例如在分配之前到numpy.float32。
    • 我可能是错的,但我相信如果你的机器是 64 位的,python float 也将是 64 位的,即我们所说的 double。因此建议将您的数据显式转换为numpy.float32 而不是通用float。
    • 使用正确的类型 (np.float32) 有效,但您的代码因紧随其后出现的另一个错误而崩溃。似乎(尽管类型正确),您正在尝试在 2 个不同形状的张量(形状为 32 x 192 的 mat1 和形状为 64 x 128 的 mat2 )之间进行一些操作。这不再与类型/转换有关。我建议您检查您的网络架构,并在需要时针对这个不同的问题打开一个新问题。
    • 错误可能是由使用与 MNIST 不同大小的输入或相关的输入引起的……祝你好运!
    猜你喜欢
    • 2021-10-29
    • 2019-09-11
    • 2018-02-20
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 2020-09-15
    • 2015-07-27
    • 2020-02-07
    相关资源
    最近更新 更多