Fastai-数据准备
Fastai数据准备
简介
数据是深度学习的立足之本,本文主要介绍Fastai框架如何进行数据加载与数据预处理。
模块划分
在之前的Fastai简介文章我提到过,Fastai最核心的API是按照应用领域(任务类型)进行划分的,打开官方文档也会看到Fastai最核心的思路:在一个DataBunch
(Fastai的数据加载器)上训练一个Model
对象,是非常简单的,只需要将数据和模型绑定到一个Learner
对象即可。
在Fastai的设计中,主要有四大应用领域,对应的四个模块名为collab
(协同过滤问题)、tabular
(表格或者结构化数据问题)、text
(自然语言处理问题)以及vision
(计算机视觉问题)。**本系列所有文章围绕都是图像数据进行处理,也就是说主要使用vision
模块。**本系列所有文章围绕都是图像数据进行处理,也就是说主要使用vision
模块。
而在vision
模块中,主要有如下几个模块:data
(数据集构建)、models
(预定义模型结构,依赖torchvision)、learner
(学习器,将模型和数据关联起来,定义了大量回调函数)、transform
(数据预处理,包括常见数据增广手段)等。
数据集构建
为了契合Fastai的API设计,这里并没有像之前Pytorch系列和Keras系列那样重构数据集为三个文件夹(对应训练集、验证集和测试集),这是考虑到Fastai的自动训练集划分的API的介绍,事实上划分数据集文件夹也是可以的,只不过多几个DataBunch
对象而已。
关于数据集读取的API都在fastai.vision.data
模块下,该模块定义了一个类ImageDataBunch
用于处理大量的Image
对象,这里的Image
对象也是由fastai.vision.data
模块下定义的一种Image类,它包含一个图片的矩阵表示、路径、维度、尺寸等属性,也包含图像显示、旋转、缩放、变换等。此外,Fastai依旧定义了不少具体视觉任务的类如用于图像分割的ImageSegment
、用于检测的ImageBBox
、用于关键点定位的ImagePoints
等。
在Fastai中数据集的处理都是基于DataBunch
类的,ImageDataBunch
是其子类,封装了很多具体的适合计算机视觉使用的方法。而在Fastai中数据的导入一般通过data_block API
实现,不过,对于常见的CV数据集格式,ImageDataBunch
已经做了封装,无需进行繁琐的API编写。这些函数用于从固定格式的文件中获取图像数据,返回的也是ImageDataBunch
对象,具体如下。
Folder(文件夹)
ImageDataBunch.from_folder(path:PathOrStr, # 数据集根目录train:PathOrStr='train', # 训练集子目录valid:PathOrStr='valid', # 验证集子目录test:Union[Path, str, NoneType]=None, # 测试集子目录valid_pct=None, # 验证集划分比例seed:int=None, # 验证集随机划分种子classes:Collection[T_co]=None, # 加载哪些类 **kwargs:Any)
从Imagenet风格的数据集内加载图像,文件存储必须是如下格式,其中train
、valid
和test
参数指定对应数据集的子文件夹名,如训练集为tra
文件夹那么则需要指定train='tra'
。
path\train\class1\class2\...valid\class1\class2\...test\
当然,如果数据集是本文案例的Caltech101的格式(下面所示),那么只需要简单指定valid_pct
作为划分训练集和验证集时验证集占整个数据集的比例即可,seed
参数指定随机划分种子,便于复现结果。
path\class1\class2\class3\
执行下面的代码。
from fastai import visiondata = vision.ImageDataBunch.from_folder("../data/101_ObjectCategories/", valid_pct=0.2, size=224)
print(data)
train_ds = data.train_ds # 取出训练集
valid_ds = data.valid_ds # 取出测试集
结果如下,生成了训练集和验证集(包括数据列表和类别列表)。
ImageDataBunch;Train: LabelList (6942 items)
x: ImageList
Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224)
y: CategoryList
accordion,accordion,accordion,accordion,accordion
Path: ..\data\101_ObjectCategories;Valid: LabelList (1735 items)
x: ImageList
Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224),Image (3, 224, 224)
y: CategoryList
dollar_bill,umbrella,Motorbikes,pigeon,nautilus
Path: ..\data\101_ObjectCategories;Test: None
上面的代码在参数中加入了size参数,该参数表示将图像的宽度和高度调整为指定尺寸,并且指定df_tfms可以自定义预处理方法。而且,通过属性获取的操作得到了具体的训练集和验证集,这会得到一个LabelList
对象,对其索引可以得到图像和标签,如img, label = train_ds[0]
,其中img
就是一个Fastai的Image
对象。
DataFrame(表格说明文件)
ImageDataBunch.from_folder(path:PathOrStr, # 数据集根目录df:DataFrame, # 包含文件路径和标签的DataFramefolder:PathOrStr=None, # 相对于Path的数据存放的子目录label_delim:str=None, # 标签分隔符valid_pct:float=0.2, seed:int=None, fn_col:IntsOrStrs=0, # 文件名列的名称或者索引号label_col:IntsOrStrs=1, # 标签列的名称或者索引号suffix:str='', # 添加的文件名后缀**kwargs:Any)
通过DataFrame获取整个数据集信息,大多数参数同上一节(下文不再说明)。
其针对的数据格式一般如下
path\data\description.csv
CSV(表格说明文件)
ImageDataBunch.from_csv(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:Union[int, str, NoneType]='infer', **kwargs:Any)
直接从CSV文件中读取数据集,省去读取为DataFrame的步骤。
文件名
很多数据集存储方式是不同的,有些数据集的标签就存放在文件名中,下面定义的三个方法用于从文件名中提取出标签。
ImageDataBunch.from_name_re(path:PathOrStr, # 文件所在路径fnames:FilePathList, 文件名列表pat:str, # 匹配模式valid_pct:float=0.2, # 同上 **kwargs)
从文件名中按照正则表达式提取标签。
ImageDataBunch.from_name_func(path:PathOrStr, fnames:FilePathList, label_func:Callable, # 标签提取函数valid_pct:float=0.2, seed:int=None, **kwargs)
根据指定的标签提取函数(自行定义)来从文件名中提取标签。
ImageDataBunch.from_lists(path:PathOrStr, fnames:FilePathList, labels:StrList, # 标签列表valid_pct:float=0.2, seed:int=None, item_cls:Callable=None, **kwargs)
需要传入一个和fnames
同等大小的列表,依次为每个文件指定标签。
数据增强
上一节介绍了构建Fastai中数据集导入部分最为核心的DataBunch
的几种常见方法,它就是输入模型的数据了。但是,在输入模型数据之前我们往往会对图像数据进行各种变换,称为数据增强(Data Augmentation)。数据增强本质上其实就是一种正则化,不过发生在数据层面而已。
Transform类
Fastai定义了大量的图像变换函数,通过实例化这些函数对象可以直接对图像数据进行操作。但是这些基础的变换函数都是以_
开头的函数如_brightness(x, change)
表示改变图像的亮度函数,注意是个函数。但是实际进行数据增强的时候往往要增加一些随机性(如随机进行翻转),所以Fastai提供了一个对这些变换进行封装的类fastai.vision.image.Transform
。该类提供共有的特性如变换函数优先级等,这些封装好的变换都在fastai.vision.transform
模块下,是不以_
开头的一系列对象(由Transform的子类实例化) ,注意是对象,同时,所有这类封装都相比于原函数多了一个参数p
,表示以概率p
进行变换,如果p
是区间则从区间内随机选择作为概率。可以通过该对象的call
方法对图像数据进行处理,如使用brightness(x, change)
。
图像变换
下面描述具体的图像变换手段,主要介绍的都是图像变换对象,变换函数只是少了概率参数p
而已。
brightness(x, change:uniform)
对图像进行亮度调整,按照change
的数值进行,其值为1表示图像为白色,为0表示黑色,为0.5表示无变化,可在0与1之间调整。
contrast(x, scale:log_uniform)
对图像进行对比度调整,sacle
表示调整量,当其值为0会将图片转为灰度图,其值为1不调整对比度,大于1会增大对比度。
crop(x, size, row_pct:uniform=0.5, col_pct:uniform=0.5)
对图像进行裁减,按照中心位置(row_pct, col_pct)
把图像裁减一个大小为size
的patch,这两个位置值以归一化格式表示。
crop_pad(x, size, padding_mode='reflection', row_pct:uniform=0.5, col_pct:uniform=0.5)
和crop
类似,不过当裁减图像大于原始图像,会自动进行填充,填充方法为’zeros’, ‘border’或者’reflection’。
dihedral(x, k:partial(uniform_int, 0, 7))
进行图像翻转并伴有一个k*90度的旋转。
dihedral_affine(k:partial(uniform_int, 0, 7))
效果同上,返回的类型不同,当目标是ImageBBox
或者ImagePoints
时使用。
flip_lr(x)
水平镜像翻转图片。
flip_affine()
同上面的以_affine
为结尾的含义。
jitter(c, magnitude:uniform)
邻域像素替换,邻域范围由magnitude
参数指定。
pad(x, padding:int, mode='reflection')
图像填充,填充模式三种:zeros
(0填充)、border
(边角填充)以及默认的reflection
(反射填充)。
perspective_warp(c, magnitude:partial(uniform, size=8)=0, invert=False)
透视变换,magnitude
是8元组参数,表示四个角归一化坐标的变换幅度。
Image.resize(self, size:Union[int,TensorImageSize])
引用自Torch的图像缩放,size为整数(正方形)或者(3,H,W)
格式。
rotate(degrees:uniform)
图像旋转,指定角度即可。
rgb_randomize(x, channel:int=None, thresh:float=0.3)
随机化RGB的某一通道,可以设置最大阈值。
skew(c, direction:uniform_int, magnitude:uniform=0, invert=False)
图像扭曲,可以指定方向和幅度。
squish(scale:uniform=1.0, row_pct:uniform=0.5, col_pct:uniform=0.5)
图像拉伸,scale<1
为横向拉伸,scale>1
为纵向拉伸。
symmetric_warp(c, magnitude:partial(uniform, size=4)=0, invert=False)
指定的透视变换。
tilt(c, direction:uniform_int, magnitude:uniform=0, invert=False)
倾斜。
zoom(scale:uniform=1.0, row_pct:uniform=0.5, col_pct:uniform=0.5)
等比例缩放。
cutout(x, n_holes:uniform_int=1, length:uniform_int=40)
孔洞产生。
get_transforms()
该函数封装在fastai.vision.transform
模块下,返回两个变换列表(每个列表包含一系列变换),用于训练集和验证集。
get_transforms(do_flip:bool=True, flip_vert:bool=False, max_rotate:float=10.0, max_zoom:float=1.1, max_lighting:float=0.2, max_warp:float=0.2, p_affine:float=0.75, p_lighting:float=0.75, xtra_tfms:Optional[Collection[Transform]]=None)
该函数可以很方便地返回大量需要的变换用于数据集的载入,如使用下述代码构建用于随机翻转变换的数据集。
from fastai.vision import transform, open_image, data
tfms = transform.get_transforms(do_flip=True)
data = data.ImageDataBunch.from_folder("../data/101_ObjectCategories/", valid_pct=0.2, size=224, ds_tfms=tfms)
train_ds, valid_ds = data.train_ds, data.valid_ds
补充说明
本文依据最新的官方文档讲解了Fastai中数据读入以及数据增强(文档)的相关知识,具体代码开源于我的Github,欢迎star或者fork。
Fastai-数据准备相关推荐
- 立即学习AI:03-使用卷积神经网络进行马铃薯分类
今天学习AI (LEARN AI TODAY) This is the 3rd story in the Learn AI Today series! These stories, or at lea ...
- C#基础教程-c#实例教程,适合初学者
C#基础教程-c#实例教程,适合初学者. 第一章 C#语言基础 本章介绍C#语言的基础知识,希望具有C语言的读者能够基本掌握C#语言,并以此为基础,能够进一步学习用C#语言编写window应用程序和W ...
- FastAI 2019课程学习笔记 lesson 2:自行获取数据并创建分类器
文章目录 数据获取 google_images_download 的安装和使用 挂载google 个人硬盘到Google colab中 删除不能打开文件 创建ImageDataBunch 训练模型 解 ...
- lego-loam数据_使用lego minifigures数据集在fastai中对datablocks api图像进行分类
lego-loam数据 The topics covered in this post are as follows 这篇文章涵盖的主题如下 Introduction 介绍 The Task 任务 T ...
- FastAI 课程学习笔记 lesson 1:宠物图片分类
文章目录 代码解析 神奇的"%" 导入fastAI 库 下载解压数据集 untar_data 获取帮助文档 help() ? ?? doc 设置路径 get_image_files ...
- 在图数据上做机器学习,应该从哪个点切入?
作者 | David Mack 编译 | ronghuaiyang 来源 | AI公园(ID:AI_Paradise) [导读]很多公司和机构都在使用图数据,想在图上做机器学习但不知从哪里开始做,希望 ...
- 120种小狗图像傻傻分不清?用fastai训练一个分类器
作者:一杯奶茶的功夫 链接:https://www.jianshu.com/p/ab35ed21df87 程序员转行学什么语言? https://edu.csdn.net/topic/ai30?utm ...
- 手把手教你用seq2seq模型创建数据产品(附代码)
原文标题:How To Create Data Products That Are Magical Using Sequence-to-Sequence Models 作者:Hamel Husain ...
- 产品经理也能动手实践的AI(一)- FastAI介绍
https://www.toutiao.com/a6671600787744883213/ 如果你还不了解AI的准确含义,请查看我之前的文章: 人人都能搞懂的AI(一) 人人都能搞懂的AI(二)- A ...
最新文章
- c mysql 索引_MySQL 多列索引的生效规则
- 广播的最佳实践——实现强制下线功能(Android_Broadcast)...
- VTK:Utilities之BrownianPoints
- 计算机采用逻辑元件的发展顺序是,全国计算机等级考试一级选择题以及答案
- iframe页面里的链接在ios设备无法点击的解决办法
- 关于equls和endsWith的悲哀(以后有equals的位置要仔细看一下了)!
- STM32F1读取MLX90614ESF非接触式温度传感器
- 微信公众平台测试账号申请
- BP神经网络的非线性曲线拟合和预测(未完)
- mac版免费吃鸡游戏(荒野行动)
- locust工具学习笔记(三)-Tasks属性、tag修饰符、TaskSet类
- MPU6050姿态解算1-DMP方式
- ETF操作实战记录:2022-2-21
- python文件处理——encoding参数,utf-8,gbk
- linux pandas教程_十分钟入门 Pandas
- Python中实现文本分类(附代码、数据集)
- 系统架构设计笔记(103)—— 标准化知识
- 如何获得新版的CCNP认证
- 手机上有没有安卓版桌面便利贴?
- Endnote引用参考文献将中文文献出现的”et al“设置为“等“的解决方法
热门文章
- MyBatis关键配置-创建会话工厂
- RedisTemplate 使用 Redis 缓存
- 骁龙660_高通骁龙660可以带动6g运行内存吗?
- zabbix监控mysql的性能_zabbix2.4.2实战监控mysql5.6性能
- 解决 IntelliJ IDEA 内置的 Tomcat 日志中显示的中文乱码
- pytorch教程龙曲良11-15
- 如何将低压精密运算放大器的性能扩展到高压高侧电流检测应用(高电流电阻采集电压电路图及误差分析)
- jquery datatable的详细用法
- 上币至iamToken
- MariaDB数据库日志