您的位置:首页 > 新闻 > 热点要闻 > 抖音制作视频的软件_东莞seo公司_今天的最新消息新闻_东莞百度搜索网站排名

抖音制作视频的软件_东莞seo公司_今天的最新消息新闻_东莞百度搜索网站排名

2024/12/28 12:03:04 来源:https://blog.csdn.net/weixin_42251091/article/details/144009318  浏览:    关键词:抖音制作视频的软件_东莞seo公司_今天的最新消息新闻_东莞百度搜索网站排名
抖音制作视频的软件_东莞seo公司_今天的最新消息新闻_东莞百度搜索网站排名

深度学习数据集的创建与读取

数据 (计算机术语)

数据(data)是事实或观察的结果,是对客观事物的逻辑归纳,是用于表示客观事物的未经加工的的原始素材。

数据可以是连续的值,比如声音、图像,称为模拟数据。也可以是离散的,如符号、文字,称为数字数据。

在计算机系统中,数据以二进制信息单元0,1的形式表示。

数据 (汉语词语)

数据就是数值,也就是我们通过观察、实验或计算得出的结果。数据有很多种,最简单的就是数字。数据也可以是文字、图像、声音等。数据可以用于科学研究、设计、查证等。

数据的形式在深度学习中是什么样的呢?数据在深度学习中是以多维数组的形式存储的,而数据代表的就是样本的数字信息特征,一般来说,对于单一样本的特征,可以像影响房价的因素那样是一维向量数组,也可以是图像特征那样是二维数组,还可以是后面介绍的语言文字那样是一维词向量数组,在训练的时候,通常会批量读取训练,所以数据集会在原有的维度基础上加一个batch_size的维度。

一直在强调,深度学习中最重要的因素之一是数据集,而刚刚入门深度学习的时候也经常会在数据集上无从下手。一般来说,针对数据集,我们需要明确2个要素,以什么样的方式存储在哪里,怎么读取用于训练。

数据存储与数据划分

将数据按照一定的格式存储起来形成的集合就是数据集。

    深度学习中,接下来我们将结合pytorch的实例详细介绍一下数据集相关知识。

除非使用已经封装好的数据集如MNIST等可以直接调用api接口导入数据,我们在网上下载也好,自己收集标注也好,都需要将图片,音频,视频,语言文字等模拟数据存储在电脑或服务器特定的路径位置下。

另一点值得注意的是下载和收集的数据要符合特定的格式(尤其不同的模型可能要求数据的格式是不同的,比如MASK-RCNN 和YOLO),这样才能方便代码读取,这里暂时不做过多的展开介绍,后面进行补充,这篇文章重点还是介绍数据的读取过程。

数据集的两个重要因素一是原始数据特征,比如图片,文字等,二是标签,比如类别或者物体分割时的位置等,在存储时要分清他们的位置,便于读取。 物体分割时比如MASK-RCNN 和YOLO,需要使用标注工具label等手动获取标签;对于分类任务,一般可以将不同类别的图片划分到不同的子文件夹里,并命名为类别或数字,读取标签的时候直接读取子文件夹名称即可。如下图是表情分类任务的数据集,以不同的数字代表表情类别。

数据集一般会划分为训练,测试和验证三个子集,网上下载好的数据一般是划分好的,若没有划分好或者是自己收集制作的,可以自己划分。最快速上手的方式就是手动分割,不过代码具有泛用性,数据划分主要是路径的处理和文件的遍历,下面以具体例子说明,最开始是data文件夹下有2个类别的子文件夹0和1,

      

现在我们想要将左图中的原始数据切割成右图中的分train,test,valid的数据集,关键点就是遍历左边的数据,然后设置比例分为三份,并按比例将其复制到右边。这里边涉及几个重要的文件处理函数,一个是os.makedirs(“path”),在检测到路径无文件夹存在时调用创建文件夹;一个是os.listdir(path),会将路径下的文件或文件夹名称储存到列表里;一个是os.walk(root_dir),是深度遍历的方式遍历自根文件夹下的所有子文件夹及文件,返回的是三元组(root,subdirs,filenames),

每一层遍历:

root保存的就是当前遍历的文件夹的绝对路径;

subdirs保存当前文件夹下的所有子文件夹的名称(仅一层,孙子文件夹不包括)

filenames保存当前文件夹下的所有文件的名称

举个例子,

-dir1

-1.jpg

-subdir1

--2.jpg

--3.jpg

-subdir2

--4.jpg

--5.jpg

os.walk() 之后遍历的结果就是

第一次遍历输出三元组

dir1 [subdir1,subdir2],1.jpg

第二次遍历输出三元组

dir/subdir1,[],[2.jpg,3.jpg]

第三次遍历输出三元组

dir/subdir2,[],[4.jpg,5.jpg]

而且需要注意的是,这三个输出是在同一个for path,dirnames,filenames in os.walk(root)下递归执行的

检测路径是否存在,若不存在,则创建此路径。

def makedir(new_dir):

    if not os.path.exists(new_dir):

        os.makedirs(new_dir)

设置路径,将它们组合在一起。相对于Python文件所在位置的相对路径。

dataset_dir = os.path.join("..", "..", "data", "RMB_data")

深度遍历,获取根文件夹和子文件夹下的文件,并对其按照设置的比例存储,以遍历第一个子文件夹为例说明一下:

 #进入深度遍历

for root, dirs, files in os.walk(dataset_dir):

#开始遍历第一个子文件夹

     for sub_dir in dirs:

#将此子文件夹下的文件名存储到列表里

         imgs = os.listdir(os.path.join(root, sub_dir))

         imgs = list(filter(lambda x: x.endswith('.jpg'), imgs))

         random.shuffle(imgs)

         img_count = len(imgs)

#设置划分比例

         train_point = int(img_count * train_pct)

         valid_point = int(img_count * (train_pct + valid_pct))

#开始按照划分比例切分图片文件

         for i in range(img_count):

             if i < train_point:

#根据归属于不同的比例填入或创建目标路径

                out_dir = os.path.join(train_dir, sub_dir)

             elif i < valid_point:

                out_dir = os.path.join(valid_dir, sub_dir)

             else:

                 out_dir = os.path.join(test_dir, sub_dir)

#创建目标路径

             makedir(out_dir)

#将文件从源文件复制到目标文件位置

             target_path = os.path.join(out_dir, imgs[i])

             src_path = os.path.join(dataset_dir, sub_dir, imgs[i])

             shutil.copy(src_path, target_path)

shutil.copy()Python中的方法用于将源文件的内容复制到目标文件或目录。它还会保留文件的权限模式,但不会保留文件的其他元数据(例如文件的创建和修改时间)。源必须代表文件,但目标可以是文件或目录。如果目标是目录,则文件将使用源中的基本文件名复制到目标中。另外,目的地必须是可写的。如果目标是文件并且已经存在,则将其替换为源文件,否则将创建一个新文件。

数据的变换

在图像数据集的训练中,经常会利用torchvision.transforms.Compose()将对图像预处理的操作以列表[,,]的形式组合在一起,然后赋值给到data_transform,并作为后续创建dataset时的参数,最常用的分为两类:

 一是图像本身的变换,如随机裁剪和翻转,图像变换的时候要注意维度保持一致。

(1)transforms.CenterCrop(size)

从图片中心截取size大小的图片。

(2)transforms.RandomCrop(size,padding,padding_mode)

随机裁剪区域。

(3)transforms.RandomResizedCrop(size,scale,ratio)

随机大小,随机长宽比的裁剪。

(1)transforms.RandomHorizationalFlip(p)

依据概率p水平翻转。

(2)transforms.RandomVerticalFlip(p)

依据概率p垂直翻转。

(3)transforms.RandomRotation(degrees,resample,expand)

二是将“图像”转化为“tensor”,我们知道,任何数据(包括图像音频等)在计算机上的计算都是要转化成数字信息的,所以我们需要将图像数据转化成pytorch中数字信息以及存储格式tensor。

transforms.Totensor()

将图像数据转换为tensor。

transforms.Normalize(mean,std,inplace)

逐通道的标准化,每个通道先求出平均值和标准差,然后标准化。Inplace表示是否原地操作。

下面代码为常用的数据变换格式,还有很多其它变换方法,可以在需要使用的时候查询。

train_transform = transforms.Compose([

    transforms.Resize((32, 32)),

    transforms.RandomCrop(32, padding=4),

    transforms.ToTensor(),

    transforms.Normalize(norm_mean, norm_std),

])

数据集转换dataset

获得并划分处理好的格式数据之后,需要利用代码将其转变为模型训练可用的数据集,所谓数据集,其实就是一个负责处理索引(index)到样本(sample)映射的一个类(class)。

数据集的三个核心参数便是从格式数据传递的存储路径,给每一个数据加的索引,以及数据集的大小(数据集总数)。

dataset(继承于Dataset)是可以我们自己用代码实现的一个类,这个类中主要包括__init__(),__getitem__(),__len__()这三个函数:

1)__init__():构造函数,该函数里面会定义存放数据的路径,一般由人给定输入。

2)__getitem__():这个函数把传入的索引Index和数据(标签)对应起来,返回数据(标签);

3)__len__():这个函数获取数据集中样本的总个数。

Pytorch提供两种数据集: Map式数据集 Iterable式数据集

目前深度学习将数据转换成训练可用的数据集有三种形式,

PyTorch集成的数据集接口

实际上,PyTorch提供了很多常用数据集的接口,如果使用这些数据集的话,可以直接使用对应的包加载,会方便很多,比如:

  • torchvision.datasets 就提供了很多视觉方向的数据集:https://pytorch.org/docs/stable/torchvision/datasets.html?highlight=torchvision datasets
  • torchtext 则提供了很多文本处理方向的数据集
  • torchaudio 提供了很多音频处理方向的数据集

当然 PyTorch也可以配合其他包来获得数据以及对数据进行处理,比如:

  • 对于视觉方面,配合 Pillow、OpenCV等
  • 对于音频处理方面,配合 scipy、librosa等
  • 对于文本处理方面,配合 Cython、NLTK、SpaCy等

实际例子来说,比如MNIST,CIFAR10等,这时可以直接利用一句代码读取出来:

在PyTorch中CIFAR10是一个写好的Dataset,我们使用时只需以下代码:

data = datasets.CIFAR10("./data/", transform=transform, train=True, download=True)

此时,代码会检查当前路径下“./data”是否存在cifar10数据集,若不存在,download为true时则启动下载,transform后面会介绍。

ImageFolder 等API

二是网络上一些公开的数据集,这时可以直接下载下来,然后利用定好的方法将其转化为模型训练的数据集,比如我们下载一些图片数据,放到一个文件夹下,这时可以使用ImageFolder这个方便的API。

FaceDataset = datasets.ImageFolder('./data', transform=img_transform)

这个是应用比较广泛的方法,因为很多时候我们会将图片放到特定的文件夹路径下。这里需要注意标签是利用api自动读取的文件夹的名称并返回列表的。

自定义一个数据集

   三则是自定义一个数据集,torch.utils.data.Dataset 是一个表示数据集的抽象类。任何自定义的数据集都需要继承这个类并覆写相关方法。这个其实是更深入的了解一下dataset数据集的本质。

Map式数据集

一个Map式的数据集必须要重写getitem(self, index),len(self) 两个内建方法,用来表示从索引到样本的映射(Map).

Map式的数据集dataset,举个例子,当使用dataset[idx]命令时,可以在你的硬盘中读取你的数据集中第idx张图片以及其标签(如果有的话);len(dataset)则会返回这个数据集的容量。

自定义类大致是这样的:

class CustomDataset(data.Dataset):#需要继承data.Dataset

    def __init__(self):

        # 可以初始化文件路径或者数据转换格式等其它处理信息

    def __getitem__(self, index):

        # 根据输入的索引参数读取一个数据和标签,可以将数据进行处理后返回数据和标签

    def __len__(self):

        # 返回数据集的大小

例子-1: 图片文件储存在“./data/faces/”文件夹下,图片的名字并不是从1开始,而是从final_train_tag_dict.txt这个文件保存的字典中读取,label信息也是用这个文件中读取。

from torch.utils import data

import numpy as np

from PIL import Image

class face_dataset(data.Dataset):

    def __init__(self,label_dict):

        self.file_path = './data/faces/'

        self.label_dict=label_dict       

    def __getitem__(self,index):

        label = list(self.label_dict.values())[index-1]

        img_id = list(self.label_dict.keys())[index-1]

        img_path = self.file_path+str(img_id)+".jpg"

        img = np.array(Image.open(img_path))

        return img,label

    def __len__(self):

        return len(self.label_dict)

Iterable式数据集

一个Iterable(迭代)式数据集是抽象类data.IterableDataset的子类,并且覆写了iter方法成为一个迭代器。这种数据集主要用于数据大小未知,或者以流的形式的输入,本地文件不固定的情况,需要以迭代的方式来获取样本索引。

小结

在实际的应用中,可以根据具体的任务或调用API,或自己重写数据集类,一般会在创建数据集的步骤中将数据变换列表transforms作为参数写进去,直接对数据进行变换处理。

数据样本加载DataLoader

创建完成数据集dataset后,还不能直接用于网络训练,下一步需要构建迭代器DataLoader作为网络训练时读取数据的方式,而数据集dataset是DataLoader实例化的一个参数。一般格式为:

train_dataloader=DataLoader(train_dataset,batch_size=16,shuffle=True)

Dataloader的一些常用参数

Dataloader的一些重要的参数如下,除了第一个 dataset参数外,一般会设置batch_size,shuffle,其他均视情况可选:

  • dataset(第一个参数,必须的参数):一个 Dataset的实例,即前面三种方式创建传入的数据集(或者其他可迭代对象)
  • batch_size:整数值,每个 batch的样本数量,即 batch大小,默认为1
  • shuffle:bool值,如果设置为 True,则在每个 epoch开始的时候,会对数据集的数据进行重新排序,默认 False
  • sampler:传入一个自定义的 Sampler实例,定义从数据集中取样本的策略,Sampler每次返回一个索引,默认为 None
  • batch_sampler:也是传入一个自定义的 Sampler实例,但是与 sampler参数不同的是,它接收的 Sampler是一次返回一个 batch的索引,默认为 None
  • num_workers:整数值,定义有几个进程来处理数据。0意味着所有的数据都会被加载进主进程,默认0
  • collate_fn:传入一个函数,它的作用是将一个 batch的样本打包成一个大的 tensor,tensor的第一维就是这些样本,如果没有特殊需求可以保持默认即可(后边会详细介绍)
  • pin_memory:bool值,如果为 True,那么将加载的数据拷贝到 CUDA中的固定内存中。
  • drop_last:bool值,如果为 True,则对最后的一个 batch来说,如果不足 batch_size个样本了就舍弃,如果为 False,也会继续正常执行,只是最后的一个 batch可能会小一点(剩多少算多少),默认 False
  • timeout:如果是正数,表明等待从加载一个 batch等待的时间,若超出设定的时间还没有加载完,就放弃这个 batch,如果是0,表示不设置限制时间。默认为0

Dataloader参数之间的互斥

值得注意的是,Dataloader的参数之间存在互斥的情况,这些初步了解即可。主要针对自己定义的采样器:

  • sampler:如果自行指定了 sampler参数,则 shuffle必须保持默认值,即 False
  • batch_sampler:如果自行指定了 batch_sampler参数,则 batch_size、shuffle、sampler、drop_last 都必须保持默认值
    如果没有指定自己是采样器,那么默认的情况下(即 sampler和 batch_sampler均为 None的情况下),Dataloader的采样策略是如何的呢:
  • sampler:shuffle = True:sampler采用 RandomSampler,即随机采样

shuffle = Flase:sampler采用 SequentialSampler,即按照顺序采样

  • batch_sampler:采用 BatchSampler,即根据 batch_size 进行 batch采样

Sampler类是一个很抽象的父类,其主要用于设置从一个序列中返回样本的规则,即采样的规则。

Dataloader其实还有一个比较重要的参数是 collate_fn,它接收一个 callable对象,比如一个函数,它的作用是将每次迭代出来的数据打包成 batch。

举个例子,如果我们在 Dataloader中设置了 batch_size为8,实际上,从 Dataloader所读取的数据集Dataset中取出数据时得到的是单独的数据,比如我们的例子中,每次采样得到一个 tuple:(image, label),因此 collate_fn 的作用就有了,它负责包装 batch,即每从数据集中抽出8个这样的 tuple,它负责把8个 (image, label)包装成一个 list: [images, labels],这个 list有两个元素,每一个是一个 tensor,比如第一个元素,实际上是一个 8×size(image) 的tensor,即给原来的数据增加了一维,也就是最前边的 batch的维度,labels也同理。

有时候我们可能会需要实现自己的包装逻辑,所以需要自定义一个函数来完成定制化的如上的内容,只要将该函数名传递给 collate_fn参数即可。

DataLoader读取数据样本的流程

综上,概括一下DataLoader读取数据样本的流程:

DataLoader首先创建一个迭代器DataloaderIter,

然后这个迭代器会去访问Sampler得到读取数据的索引值;

根据这个索引值去访问创建好的数据集DataSet;

利用DataSet的getitem函数读取对应索引值的样本数据;

然后利用collate_fn将独立的样本数据打包成batch_size大小的Batch Data。

深度学习数据集的创建与读取流程

而整个PyTorch中深度学习数据读取的流程是这样的:

1. 创建Dateset

2. Dataset传递给DataLoader

3. DataLoader迭代产生训练数据提供给模型

对应的一般都会有这三部分代码

# 创建Dateset(可以自定义)

    dataset = face_dataset # Dataset部分自定义过的face_dataset

# Dataset传递给DataLoader

    dataloader = torch.utils.data.DataLoader(dataset,batch_size=64,shuffle=False,num_workers=8)

# DataLoader迭代产生训练数据提供给模型

    for i in range(epoch):

        for index,(img,label) in enumerate(dataloader):

            pass

到这里应该就PyTorch的数据集和数据传递机制应该就比较清晰明了了。Dataset负责建立索引到样本的映射,DataLoader负责以特定的方式从数据集中迭代的产生一个个batch的样本集合。在enumerate过程中实际上是dataloader按照其参数sampler规定的策略调用了其dataset的getitem方法。其中,还会涉及数据的变化形式。

参考资料

torch.utils.data — PyTorch 2.5 documentation

https://gladdduck.github.io/2022/11/09/笔记-Pytorch数据集加载/

深度之眼 pytorch学习课程

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com