不同数据集文件存放方式来构建dataset,dataloader

Posted 小啊磊BLUE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不同数据集文件存放方式来构建dataset,dataloader相关的知识,希望对你有一定的参考价值。

不同数据集文件存放方式来构建dataset,dataloader

文章目录


前言

最近在练习深度学习一些基础代码,对不同的数据集的图片方式存储不同来构建dataset,并创建train_dataloader,test_dataloader


一、数据集存放方式一

1.数据集存放方式

  • 上述的数据集文件夹是weather_photos,在该文件夹下面共有四个子文件夹,分别是cloudy, rain, shine, sunrise
  • cloudy文件里面放的是所有的cloudy天气图片,其他几个分别是对应的天气图片
  • 共有四个类别, cloudy, rain, shine, sunrise,常用于分类

2.构建train_dataset, test_dataset

total_dir = r'/root/autodl-tmp/weather_photos/'

transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])

total_data = torchvision.datasets.ImageFolder(total_dir, transform)
train_size = int(len(total_data) * 0.8)
test_size = len(total_data) - train_size
print(train_size, test_size)

train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])

3.构建train_dataloader, test_dataloader

train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=1)
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=True, num_workers=1)
  • 构建train_dataloader, test_dataloader后我们可以看看类别对名称的索引,名称对类别的索引, 采用列表推导式
print(total_data.class_to_idx)       # 'cloudy': 0, 'rain': 1, 'shine': 2, 'sunrise': 3
idx_to_class = dict((v, k) for k, v in total_data.class_to_idx.items())
print(idx_to_class)                  # 0: 'cloudy', 1: 'rain', 2: 'shine', 3: 'sunrise'

4. 进行绘图查看dataloader图片

imgs, labels = next(iter(train_dataloader))
plt.figure(figsize=(12, 8))                                # 画布大小
for i, (img, label) in enumerate(zip(imgs[:6], labels[:6])):
    img = img.permute(1, 2, 0).numpy()
    img = (img + 1) / 2
    plt.subplot(2, 3, i+1)
    plt.title(idx_to_class[label.item()])
    plt.imshow(img)
plt.show()

二、数据集存放方式二

1.数据集存放方式

  • 数据集存放方式为train, test两个文件夹,其中子文件夹分别是类别的文件夹,类别文件夹中存放的是类别图片
  • 用于图像分类
  • 46-data总文件夹, train,test为训练和测试文件夹, 子目录为类别文件夹

2.构建train_dataset, test_dataset

transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

train_dataset = torchvision.datasets.ImageFolder(root=r'/root/autodl-tmp/46-data/train',
                                                transform=transform)
test_dataset = torchvision.datasets.ImageFolder(root=r'/root/autodl-tmp/46-data/test',
                                                transform=transform)

3.构建train_dataloader, test_dataloader

print(train_dataset.class_to_idx)
idx_to_class = dict((v, k) for k, v in train_dataset.class_to_idx.items())
print(idx_to_class)


train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=True)

4. 进行绘图查看dataloader图片

imgs, labels = next(iter(train_dataloader))

plt.figure(figsize=(12, 8))                                # 画布大小
for i, (img, label) in enumerate(zip(imgs[:6], labels[:6])):
    img = img.permute(1, 2, 0).numpy()
    img = (img + 1) / 2
    plt.subplot(2, 3, i+1)
    plt.title(idx_to_class[label.item()])
    plt.imshow(img)
plt.show()

三、数据集存放方式三

1.数据集存放方式

  • 所有的类别图片都放在一个文件夹下面,图片的命名通过类别来进行区分
  • 我们的目标是:构建train, test两个文件夹,其中子文件夹分别是类别的文件夹,类别文件夹中存放
    的是类别图片
  • 目标文件夹方式逻辑如下:
base_dir = './4_weather'
if not os.path.isdir(base_dir):
    os.makedirs(base_dir)                                 # 如果没有base_dir, 就创建base_dir
    train_dir = os.path.join(base_dir, 'train')           # 在base_dir下加入train目录
    test_dir = os.path.join(base_dir, 'test')
    os.makedirs(train_dir)                                # 创建 train_dir 目录
    os.makedirs(test_dir)

# train文件夹下创建cloudy, rain, shine, sunrise文件夹
specises = ['cloudy', 'rain', 'shine', 'sunrise']
cloudt_dir = './4_weather/train/cloudy'
if not os.path.isdir(cloudt_dir):
    for train_or_test in ['train', 'test']:
        for spec in specises:
            os.makedirs(os.path.join(base_dir, train_or_test, spec))

# os.listdir(image_dir)                                    # 列出image_dir文件夹所有文件的名称
image_dir = './dataset2'
for i, img_name in enumerate(os.listdir(image_dir)):
    for spec in specises:
        if spec in img_name:                               # 如果 spec 在 img_name 中
                s = os.path.join(image_dir, img_name)
                if i%5==0:
                    d = os.path.join(base_dir, 'test', spec, img_name)
                else:
                    d = os.path.join(base_dir, 'train', spec, img_name)
                shutil.copy(s, d)                          # s拷贝到d
# 查看每个cloudy, rain, shine, sunrise文件下图片的个数
for train_or_test in ['train', 'test']:
    for spec in specises:
        print(train_or_test, spec, len(os.listdir(os.path.join(base_dir, train_or_test, spec))))
  • 经过上述代码,我们能把图片放在对应的文件夹里面

2.构建train_dataset, test_dataset

# torchvision.dataset.ImageFolder: 从分类文件夹中创建dataset数据, 文件为train, test
# train_dataset的root 为 train 目录,4_weather下的train目录, train目录下为类别目录
train_dataset = torchvision.datasets.ImageFolder(root='./4_weather/train',
                                                 transform=transform
                                                 )

test_dataset = torchvision.datasets.ImageFolder(root='./4_weather/test',
                                                transform=transform
                                                )

3.构建train_dataloader, test_dataloader,并绘图

# train_dataset.classes: 根据分的文件夹的名字来确定的类别
# train_dataset.class_to_idx: 按顺序为这些类别定义索引为0, 1...
print(train_dataset.classes)                               # ['cloudy', 'rain', 'shine', 'sunrise']
print(train_dataset.class_to_idx)                          # 'cloudy': 0, 'rain': 1, 'shine': 2, 'sunrise': 3

train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)

imgs, labels = next(iter(train_dataloader))
print(imgs.shape)                                          # torch.Size([32, 3, 224, 224])

id_to_class = dict((v, k) for k, v in train_dataset.class_to_idx.items())
print(id_to_class)                                         # 0: 'cloudy', 1: 'rain', 2: 'shine', 3: 'sunrise'
print(id_to_class[1])                                      # rain

plt.figure(figsize=(12, 8))                                # 画布大小
for i, (img, label) in enumerate(zip(imgs[:6], labels[:6])):
    img = img.permute(1, 2, 0).numpy()
    img = (img + 1) / 2
    plt.subplot(2, 3, i+1)
    plt.title(id_to_class[label.item()])                   # plt.title(id_to_class.get(label.item()))
    plt.imshow(img)
plt.show()

四、数据集存放方式四

1.数据集存放方式

  • 与数据集三存放方式相同
  • 这里才用构建 data.Dataset类来创建train_dataset, test_dataset

2.确定所有图片路径以及对应的标签列表

all_imgs_path = glob.glob(r'./dataset2/*.jpg')                     # 返回所有图片地址路径
print(all_imgs_path)

# 对于定义的 My_dataset 类实例化, 只需传入 __init__()的参数
# My_dataset 共有两个方法: __len__(), __getitem__()
weather_dataset = My_dataset(all_imgs_path)

weather_dataloader = DataLoader(weather_dataset, batch_size=32)
print(len(weather_dataset))

species = ['cloudy', 'rain', 'shine', 'sunrise']
species_to_idx = dict((c, i) for i, c in enumerate(species))
print(species_to_idx)                                           # 'cloudy': 0, 'rain': 1, 'shine': 2, 'sunrise': 3

idx_to_spec = dict((v, k) for k, v in species_to_idx.items())
print(idx_to_spec)                                              # 0: 'cloudy', 1: 'rain', 2: 'shine', 3: 'sunrise'

# 创建 all_imgs_path 对应的列表
all_labels = []
for img in all_imgs_path:
    for i, c in enumerate(species):
        if c in img:                                            # 如果 c 在 img 中
            all_labels.append(i)

print(all_labels)                                               # 得到所有图片的标签

3.构建dataset类

# 创建输入
transform = transforms.Compose([
    transforms.Resize((96, 96)),
    transforms.ToTensor(),
])


# def __init__(): imgs_path所有图片的路径, labels所有图片的标签(列表形式)
# 自定义创建 dataset 类
class Weather_data(data.Dataset):
    def __init__(self, imgs_path, labels, transform):
        self.imgs = imgs_path
        self.labels = labels
        self.transform = transform

    def __getitem__(self, index):
        img = self.imgs[index]
        label = self.labels[index]

        pil_img = Image.open(img)                               # 打开图片img, 此时img为路径
        pil_img = pil_img.convert('RGB')
        data = self.transform(pil_img)
        return data, label

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

4.构建train_dataset, test_dataset

# 划分测试数据, 验证数据
# 把图片路径和标签 转为 array
index = np.random.permutation(len(all_imgs_path))
all_imgs_path = np.array(all_imgs_path)[index]
all_labels = np.array(all_labels)[index]

# 进行切片
s = int(len(all_imgs_path)*0.8)
train_imgs = all_imgs_path[:s]
train_label = all_labels[:s]
test_imgs = all_imgs_path[s:]
test_label = all_labels[s:]

train_dataset = Weather_data(train_imgs, train_label, transform)
test_dataset = Weather_data(test_imgs, test_label, transform)

train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)

imgs_bath, labels_batch = next(iter(train_dataloader))
print(imgs_bath.shape)                                                 # torch.Size([32, 3, 96, 96])
print(labels_batch.shape)                                              # torch.Size([32])



以上是关于不同数据集文件存放方式来构建dataset,dataloader的主要内容,如果未能解决你的问题,请参考以下文章

使用频繁项集挖掘来构建关联规则?

h5文件简介

从DB中取出的数据集(如存放在datatable里)怎么按照其中某些字段group分组

尝试将数据表添加到数据集

SparkSQL---实战应用

Pytorch学习笔记(9) 通过DataSet、DatasetLoader构建模型输入数据集