DataLoader问题解决:RuntimeError: stack expects each tensor to be equal size, but got [3, 200, 200]entry1

        最近,在数据集处理并载入DataLoader进行训练的时候出现了问题:

RuntimeError: stack expects each tensor to be equal size, 
but got [3, 200, 200] at entry 0 and [1, 200, 200] at entry 1

        我看了一下,大意就是维度也就是通道数不匹配,所以我觉得应该是数据集图片出现了问题。以下是我的普通数据集处理代码:

import torch
import torchvision.transforms as transforms
from torch.utils.data import Dataset, DataLoader
import os
from PIL import Image

transform = transforms.Compose([
            transforms.RandomCrop((200, 200)),    #需要进行同意大小,不然会报错
            transforms.ToTensor(),
])

class PreprocessDataset(Dataset):
    """预处理数据集类"""

    def __init__(self, HRPath):
        """初始化预处理数据集类"""
        img_names = os.listdir(HRPath)
        self.HR_imgs = [HRPath + "/" + img_name for img_name in img_names]

    def __len__(self):
        """获取数据长度"""
        return len(self.HR_imgs)

    def __getitem__(self, index):
        """获取数据"""
        HR_img = self.HR_imgs[index]

        HR_img = Image.open(HR_img)

        HR_img = transform(HR_img)

        return HR_img     

if __name__ == '__main__':
    HRPath = r"D:\datasets\ImageNet\train"
    datasets = PreprocessDataset(HRPath)
    trainData = DataLoader(datasets, batch_size=1, shuffle=False)
    for i, HR_img in enumerate(trainData):
        print(i, HR_img.shape)

          我一张一张图片放入DataLoader,然后按顺序一张一张的查看它们的维度,然后出现如下错误:

'''结果'''
146 torch.Size([1, 3, 200, 200])
147 torch.Size([1, 3, 200, 200])

ValueError: empty range for randrange() (0,-55, -55)

        我找到出错前按顺序查到了第149(从0开始)张图片的维度,点开发现这张图片的最短边小于200,不能进行随机裁剪transforms.RandomCrop((200, 200)),所以我进行了transforms.Resize(400),把图片最短边放大到400。

transform = transforms.Compose([
            transforms.Resize(400),
            transforms.RandomCrop((200, 200)),    #需要进行同意大小,不然会报错
            transforms.ToTensor(),
])

        在次运行并不发生错误,但这是在DataLoader的batch_size=1张图片的情况下。所以把batch_size改成多张图片再次运行:

if __name__ == '__main__':
    HRPath = r"D:\datasets\ImageNet\train"
    # os.listdir(HRPath)
    datasets = PreprocessDataset(HRPath)
    a = datasets[89]
    print(a.shape)
    trainData = DataLoader(datasets, batch_size=16, shuffle=False)
    for i, HR_img in enumerate(trainData):
        print(i, HR_img.shape)

        发生错误:

'''结果'''
0 torch.Size([16, 3, 200, 200])
1 torch.Size([16, 3, 200, 200])
2 torch.Size([16, 3, 200, 200])
3 torch.Size([16, 3, 200, 200])
4 torch.Size([16, 3, 200, 200])

RuntimeError: stack expects each tensor to be equal size, 
but got [3, 200, 200] at entry 0 and [1, 200, 200] at entry 9

        从不出错的结果上看,定位图片问题所在的索引应该在80-96之间,那么缩小问题图片的方位,把batch_size=2:

if __name__ == '__main__':
    HRPath = r"D:\datasets\ImageNet\train"
    # os.listdir(HRPath)
    datasets = PreprocessDataset(HRPath)
    a = datasets[89]
    print(a.shape)
    trainData = DataLoader(datasets, batch_size=2, shuffle=False)
    for i, HR_img in enumerate(trainData):
        print(i, HR_img.shape)

        错误定位到第89或者第90张图片:

'''结果'''
0 torch.Size([2, 3, 200, 200])
...
...
43 torch.Size([2, 3, 200, 200])

RuntimeError: stack expects each tensor to be equal size, but got [3, 200, 200] at entry 0 and [1, 200, 200] at entry 1

        输出第89张图片的维度:

if __name__ == '__main__':
    HRPath = r"D:\datasets\ImageNet\train"
    # os.listdir(HRPath)
    datasets = PreprocessDataset(HRPath)
    a = datasets[89]
    print(a.shape)

        结果:

torch.Size([1, 200, 200])

        真的是通道数不统一,醉了啊!

        解决方法,在图片预处理的时候,将所有图片都转成"RGB"三通道的模式:

HR_img = Image.open(HR_img).convert('RGB')   #全部以三通道形式打开

        解决完成!!!!

b410012723e5494c8ae6a821d95aefd2.png

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
这个错误通常发生在使用PyTorchDataLoader加载数据时,输入数据的尺寸不一致导致的。 解决方法是将所有输入数据的尺寸改为相同大小,可以通过padding或者截断的方式实现。具体来说,可以通过下面两种方式解决这个问题: 1. Padding方式 在加载数据时,将所有的数据填充到相同的尺寸。可以使用PyTorch中的torch.nn.functional.pad函数实现。具体代码如下: ```python from torch.utils.data import DataLoader import torch # 定义一个自定义数据集 class MyDataset(torch.utils.data.Dataset): def __init__(self, data_list): self.data_list = data_list def __getitem__(self, index): data = self.data_list[index] inputs = torch.nn.functional.pad(data['inputs'], [0, max_shape[1] - data['inputs'].shape[1], 0, max_shape[0] - data['inputs'].shape[0]]) labels = data['labels'] return inputs, labels def __len__(self): return len(self.data_list) # 加载数据 dataset = MyDataset(data_list) train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers) ``` 其中,data_list是一个列表,包含了所有的数据,每个数据的输入(inputs)和标签(labels)尺寸可以不同。 2. 截断方式 如果不想使用padding方式,也可以将所有数据截断到相同的尺寸。具体代码如下: ```python from torch.utils.data import DataLoader import torch # 定义一个自定义数据集 class MyDataset(torch.utils.data.Dataset): def __init__(self, data_list): self.data_list = data_list def __getitem__(self, index): data = self.data_list[index] inputs = data['inputs'][:, :max_shape[1]] labels = data['labels'] return inputs, labels def __len__(self): return len(self.data_list) # 加载数据 dataset = MyDataset(data_list) train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers) ``` 其中,max_shape是所有数据中的最大尺寸,data_list是一个列表,包含了所有的数据,每个数据的输入(inputs)和标签(labels)尺寸可以不同。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值