第二篇 FastAI数据准备「建议收藏」

第二篇 FastAI数据准备「建议收藏」一、FastAI代码组织结构(文档链接)FastAI库主要涉及神经网络在如下四个领域的应用:collab(协同滤波问题)、tabular(结构化数据或者说表格数据处理)、text(自然语言处理)、vision(机器视觉)。对每一领域(除了collab),其下又会按照如下结构组织代码:(1)data:定义了模型所需的数据集类。(2)transform:数据预处理(如对图像数据的图像…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、Fast AI代码组织结构 (文档链接)

Fast AI库主要涉及神经网络在如下四个领域的应用:collab(协同滤波问题)、tabular(结构化数据或者说表格数据处理)、text(自然语言处理)、vision(机器视觉)。对每一领域(除了collab),其下又会按照如下结构组织代码:

  • (1) data:定义了模型所需的数据集类。
  • (2) transform:数据预处理(如对图像数据的图像增强,表格数据的数据清洗,文本数据的符号化以及数字化)
  • (3) models:定义了相应的网络模型。
  • (4) learner:定义了将数据和模型关联起来的类,并定义了一系列回调函数。

本系列博客所关注的vision包,同样是按照如上结构进行组织的,同时也定义了专用于视觉处理的对象:

  • (1) vision.Image定义了Fast AIImage对象,以及对其进行操作的函数。
  • (2) vision.data定义了专用于视觉应用的ImageDataBunch数据集,以及可从DataBunch构建的用于视觉应用的函数。
  • (3) vision.transform定义了可用于数据增强的变换。
  • (4) vision.learner定义了可用于训练网络或迁移学习的一些函数。

若要使用vision包的功能,仅需如下语句进行导入相关定义:

from fastai.vision import *

二、 vision.Image数据类型(fastai/vision/image.py)

Fast AI用于图像处理的基础类型为Image,是在PIL.Image类型上构建的,并封装了一些常用函数。

1. 构建Image对象

Fast AI提供了一个将图像文件读取为vision.Image对象的函数open_image(定义在fastai/vision/image.py文件中):

open_image( fn:PathOrStr,               # 文件路径
            div:bool=True,              # 是否除以255
            convert_mode:str='RGB',     # 转换方式,同PIL.Image
            cls:type=Image,             # 返回的类型
            after_open:Callable=None)   # 打开文件后的回调

上述函数以PIL.Image.open()方式打开fn指定的文件后,做after_open的处理,然后调用pil2tensor()函数将之转换成float32型的tensor(会进行维度的交换调整,调整后变为C x H x W),依据div决定是否做归一化操作(默认是做归一化操作的),最后转换为cls类型的变量。cls默认使用vision.Image类型。

所以,Image类型还可使用C x H x W形状的float32型的tensor类直接进行初始化。

2. Image对象的一些通用属性
  • Image.data: 图像像素数据,以tensor形式存储。
  • Image.shape: channels x height x width
  • Image.size: height x width
3. Image对象的一些通用函数
  • Image.show()函数,用于显示图像
    Image.show(
        ax:Axes=None,       # 指定用于显示图像的图对象(由matplotlib的相关函数生成)
        figsize:tuple=(3, 3),   # 图的大小
        title:Optional[str]=None,   # 图的标题
        hide_axis:bool=True,    # 隐藏坐标轴
        cmap:str=None,          # color map, 与matplotlib中的cmap一致
        y:Any=None,         # 是否有额外的显示,如定位框、图像掩膜之类的
        **kwargs
    )
  • Image.rotate()函数,用于图像旋转,这是一个神奇的函数,在Image类及其父类ItemBase中,均找不到它的定义,不过应该和PIL.Image.rotate()函数类似。对于旋转后需要扩充的像素,采用的是反射补全。
  • Image.resize()函数,用于图像缩放,其参数为一个整数,或者HxW型的元组。
  • Image.apply_tfms()函数,用于图像变换:
    apply_tfms(
          tfms:Union[Callable, Collection[Callable]],  # 变换列表
          do_resolve:bool=True,   # 是否重新设置随机化参数。比如对于图像分割,
                                  # 对image和mask需要做同样的缩放或平移,
                                  # 此时即需要设置do_resolve=False
          xtra:Optional[Dict[Callable, dict]]=None, # 变换所需的额外的参数
          size:Union[int, TensorImageSize, NoneType]=None, # 输出图片的尺寸 
          resize_method:ResizeMethod=None, # 如何达到最终所要的尺寸 [crop, pad, squish]
          mult:int=None, # 保证最终所得图像的尺寸是mult的倍数
          padding_mode:str='reflection', # 填充方法 ["zero", "border", "reflection"]
          mode:str='bilinear', remove_out:bool=True) → Tensor

除去vision.Image类外,Fast AI还定义了一些用于具体任务的类,如用于图像分割的ImageSegment类,用于目标检测的ImageBBox类,用于关键点定位的ImagePoints类等。这些将在相关应用场景下进行介绍。

三、 用于灌入网络的数据装配类型vision.ImageDataBunch类(fastai/vision/data.py)

由前一博客的示例,Fast AI会将训练集、验证集、测试集的数据迭代器组合成DataBunch对象。而对于视觉领域的应用,Fast AI提供了更为合适的数据装配类型:ImageDataBunch类。

对于视觉任务而言,其数据一般有两种组织方式:

  • ImageNet类的数据组织形式:每类的图像位于各自的文件夹下:

      path\
      	train\ 
                  class1\     class2\ ...
      	valid\
                  class1\     class2\ ...
       	test\
    
  • csv文件给出图像以及对应的label:

      path\
      	train\  test\   labels.csv
    

针对这些情形,Fast AI提供了用于构建ImageDataBunch的6种工厂类方法。这6种方法均是基于ImageDataBunch.create_from_ll()方法。由前所述,ImageDataBunch仅是整合了用于灌入网络的数据加载器(即训练集、验证集和可选的测试集),因此,create_from_ll()方法也很简单:指定训练集、验证集、测试集的文件列表,指定网络每次读取的数据的大小(batch size),指定对数据进行的变换等等。

@classmethod
def create_from_ll(cls, 
    lls:LabelLists, # 文件列表
    bs:int=64, val_bs:int=None, # batch size
    ds_tfms:Optional[TfmList]=None, # 对数据进行的变换
    num_workers:int=defaults.cpus, 
    dl_tfms:Optional[Collection[Callable]]=None, 
    device:torch.device=None,
    test:Optional[PathOrStr]=None, # 测试数据集的路径
    collate_fn:Callable=data_collate, 
    size:int=None, # 图像大小
    no_check:bool=False,
    resize_method:ResizeMethod=None, 
    mult:int=None, padding_mode:str='reflection',
    mode:str='bilinear', 
    tfm_y:bool=False # 是否对标签数据进行变换,如在图像分割任务中,是否对mask进行变换
)->'ImageDataBunch':

实际上很少直接调用这个看着很复杂的函数,而是调用6种工厂类函数。这些工厂类函数大同小异,仅是在如何提供数据标签方面有所差别。下面以fastai.URLs.MNIST_SAMPLE数据为例演示其用法。

1. URLs.MNIST_SAMPLE数据说明
path = untar_data(URLs.MNIST_SAMPLE)

会将数据文件下载至~/.fastai/data目录下。数据目录结构为

mnist_sample\
    labels.csv
    train\(12396)
        3\(6131)  7\(6265)
    valid\(2038)
        3\(1010)  7\(1028)         

数据仅包含MNIST手写数字集的37两类,按照ImageNet数据的组织格式存储,同时以labels.csv文件提供文件名与类别的对应关系。其中labels.csv中的每条记录的格式为:(注意其中的labels不再是37,而变成了01)

第二篇 FastAI数据准备「建议收藏」

图 1. labels.csv记录格式
2. 使用文件夹提供数据标签:from_folder()工厂类方法

from_folder()的函数签名如下:

@classmethod
def from_folder(cls,
    path:PathOrStr,  # 数据目录,包含train、valid等分类。
    train:PathOrStr='train', # 训练集的文件夹名称,默认为train
    valid:PathOrStr='valid', # 验证集的文件夹名称,默认为valid
    valid_pct=None, seed:int=None, # 用于划分train和valid数据集的比例参数,以及随机种子
                    # 如果设置了valid_pct参数,则train、valid参数指定的文件夹不再起作用
    classes:Collection=None, # 可以指定选取哪些类
    **kwargs:Any)->'ImageDataBunch':

对于MNIST_SAMPLE数据:

data = ImageDataBunch.from_folder(path, size=24)
3. 使用panda.DataFrame对象提供数据标签:from_df()工厂类方法

from_df()的函数签名如下:

@classmethod
def from_df(cls,
    path:PathOrStr, # 数据目录
    df:pd.DataFrame, # 存储图像文件及其对应标签的DataFrame
    folder:PathOrStr=None,  # 相对于path的子路径
    label_delim:str=None,
    valid_pct:float=0.2, seed:int=None, # 用于划分train和valid数据集的比例参数,以及随机种子
    fn_col:IntsOrStrs=0, label_col:IntsOrStrs=1, # 数据文件和标签的列
    suffix:str='', # 文件ID是否需要添加后缀
    **kwargs:Any)->'ImageDataBunch'

对于MNIST_SAMPLE数据:

df = pd.read_csv(path/'labels.csv', header='infer')
data = ImageDataBunch.from_df(path, df=df)

其中labels.csv可能会包含表头,所以会使用header='infer'来做自动处理。如果labels.csv中记录的文件路径和path之间仍有子路径,则可通过folder参数进行设置。如果labels.csv中记录的文件路径没有后缀,则可通过suffix参数指定。如:图像数据以jpg格式存储在/home/user/data/train/路径下,设置path="/home/user/data",另外labels.csv中的文件路径为:img_1img_2……,则可设置:folder="train"suffix=".jpg"

4. 使用csv文件提供数据标签:from_csv()工厂类方法

from_csv()是基于from_df()函数实现的,其函数签名如下:

@classmethod
def from_csv(cls,
    path:PathOrStr, # 数据目录
    folder:PathOrStr=None, 
    label_delim:str=None, 
    csv_labels:PathOrStr='labels.csv', # csv文件名
    valid_pct:float=0.2, seed:int=None,
    fn_col:int=0, label_col:int=1,
    suffix:str='', delimiter:str=None, 
    header:Optional[Union[int,str]]='infer',
    **kwargs:Any)->'ImageDataBunch'

其中csv文件应位于path路径下,如果csv文件的名称为labels.csv,则可省略csv参数;csv文件中指定的数据,应位于path/folder路径下。

对于MNIST_SAMPLE数据:

data = ImageDataBunch.from_csv(path, size=24)
5. 使用文件名提取数据标签:from_name_func()工厂类方法

from_name_func()函数的签名如下:

@classmethod
def from_name_func(cls,
    path:PathOrStr,         # 数据文件路径
    fnames:FilePathList,    # 数据文件列表
    label_func:Callable,    # 从文件名中提取标签的函数
    valid_pct:float=0.2,
    seed:int=None,**kwargs)

注意,函数将依据fnames中存储的文件路径fname来查找文件,而不是以path/fname为路径。
对于MNIST_SAMPLE数据,其数据文件路径形为:

'/home/user/.fastai/data/mnist_sample/train/3/7463.png'
'/home/user/.fastai/data/mnist_sample/train/7/3087.png'

故可通过检查\3\\7\是否在路径中来判断文件类别:

df = pd.read_csv(path/'labels.csv', header='infer')
fnames = [path/file for file in df["name"]]
def get_labels(file_path):
    return '3' if '/3/' in str(file_path) else '7'
data = ImageDataBunch.from_name_func(path, fnames, label_func=get_labels, size=24)
6. 使用正则表达式提取数据标签:from_name_re()工厂类方法

from_name_re()是基于from_name_func()实现的,其函数签名为:

def from_name_re(cls,
    path:PathOrStr,
    fnames:FilePathList,
    pat:str,                # 正则表达式
    valid_pct:float=0.2,
    **kwargs)

对于MNIST_SAMPLE数据,可通过提取数据文件所在的文件夹名称(即"3"或者"7")来指定文件标签:

pat = r"/(\d)/\d+\.png$"
data = ImageDataBunch.from_name_re(path, fn_paths, pat=pat, size=24)
7. 使用列表提供数据标签:from_list()工厂类方法

from_list()的函数签名为:

@classmethod
def from_lists(cls,
    path:PathOrStr,
    fnames:FilePathList,    # 文件名称列表
    labels:Collection[str], # 标签列表
    valid_pct:float=0.2, seed:int=None,
    item_cls:Callable=None, **kwargs)

对于MNIST_SAMPLE数据:

df = pd.read_csv(path/'labels.csv', header='infer')
fn_paths = [path/file for file in df["name"]]
def get_labels(file_path):
    return '3' if '/3/' in str(file_path) else '7'
labels_ls = list(map(get_labels, fn_paths))
data = data = ImageDataBunch.from_lists(path, fn_paths, labels=labels_ls, size=24)

Fast AI提供了一套整合数据文件与标签文件的数据类型和API,上述6种工厂类方法均是在其基础上进行构建的。而这些数据类型和API也提供了足够的灵活性,可在这6种工厂类方法不能覆盖的应用情景下(如想要通过文件夹区分训练集和验证集,而通过csv文件提供数据标签),方便地构建出所需的数据集和标签集。这部分内容将在下一博客中进行阐述。

一些有用的链接

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196033.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • js删除数组中的一个元素_js数组包含某个元素

    js删除数组中的一个元素_js数组包含某个元素目录第一种:删除最后一个元素pop删除slice删除splice删除for删除length删除第二种:删除第一个元素shift删除slice删除splice删除第三种:删除数组中某个指定下标的元素splice删除for删除第四种:删除数组中某个指定元素splice删除filter删除forEach、m…

  • [M枚举] lc5. 最长回文子串(枚举+中心拓展+区间dp)「建议收藏」

    [M枚举] lc5. 最长回文子串(枚举+中心拓展+区间dp)「建议收藏」文章目录1.题目来源2.题目解析方法一:枚举1.题目来源链接:lc5.最长回文子串2.题目解析方法一:枚举回文串一共有两种,即长度为奇数的回文串,长度为偶数的回文串。我们可以枚举回文串的中心(偶数长度回文串假想一个中心就行了),然后分别拿两个指针l=i-1,r=i+1向左右两边同时拓展,若s[l]=s[r]则,l–,r++。一直进行该操作,直到不等或一方到达边界位置。我们针对每一个枚举位置i,都考虑其两种情况,即偶数,奇数都考虑一遍,取个最大的就行了。

  • 教你如何快速将网站开发为桌面应用

    教你如何快速将网站开发为桌面应用

  • Tomcat配置SSL证书(PFX证书)

    Tomcat配置SSL证书(PFX证书)Symantec提供免费版SSL,可快速免费申请一、什么是SSL(证书)?    SSL证书服务(AlibabaCloudSSLCertificatesService)由阿里云联合多家国内外数字证书管理和颁发的权威机构、在阿里云平台上直接提供的服务器数字证书。您可以在阿里云平台上直接购买、或者免费获取所需类型的数字证书,并一键部署在阿里云…

  • com QueryInterface「建议收藏」

    com QueryInterface「建议收藏」客户同组件的交互都是通过一个接口完成的。在客户查询组件的其他接口时,也是通过接口完成的。这个接口就是IUnknown。它在UNKNWN.H头文件定义 :如下

  • earlysuspend[通俗易懂]

    earlysuspend[通俗易懂]earlysuspend================ 头文件:linux/earlysuspend.h使用earlysuspend—————— 另外andorid还支持内核中的earlysuspend操作,因为kenerl此前的电源管理就是把几乎所有的设备 都拖入睡眠模式,但多数情况下有些设备还不需要睡眠。ealysuspen

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号