前言
随着Pytorch-1.0预览版的发布,fastai-v1.0版也出世了。
之前的fastai的版本是0.7
,而现在最新的fastai是1.0.6版本(稳定版)
,最低Pytorch版本要求是1.0。而在fastai之前的版本使用的Pytorch版本是0.4.1。
需要注意,对于现在最新的fastai的1.0版本来说只可以使用Pytorch-v1.0了。使用别的版本会有兼容问题。
fastai并不是简单意义上的将Pytorch封装了一遍,而是类似于Keras与TensorFlow的关系。Keras将TensorFlow的强大性易用化。而fastai也一样,在Pytorch的基础上使开发者可以快速地利用Pytorch后端进行开发,不仅仅是研究(Research),就算是生产(Produce)也游刃有余。
本篇文章所说的fastai基于的版本是1.0.7-dev版,fastai版本更新很快,不过基本的训练代码流程已经都定型,其他的也都是小修小改,对整体的编写代码影响不大,大家大可放心。
fastai-v1.0更新频率
快速入门
快速入门的意义不用多说,目前为止机器学习深度学习任务中我们重点关注的是其网络构架和损失函数以及图像预处理等的设计。但是我们在实际训练中难免会写一些其余的与构造算法无关的代码,这些代码作为工具是必不缺少的,但是又极为耗时。
为了避免重复地造工具代码的轮子,fastai提供了封装好的框架,供我们使用:
仅仅几行代码,就可以训练MNIST达到98%的准确率。
本文的目的在于快速带领大家入门最新版的fastai-v1.0,从而快速搭建我们的深度学习应用。
安装fastai
怎么安装官方的github主页上已经说得很详细的,主页上的安装说明是1.0版的,可以使用pip或者conda安装,不过因为这个1.0版本刚刚出来,因此会有很多的小bug和漏洞,目前比较稳定的可用的1.0.6版本,可以通过pip或者conda下载安装。
当然也可以通过pip的可编辑的高级安装模式安装fastai的nightly版,以跟踪最新的fastai库,官方给出了安装命令,我这里搬运一下:
git clone https://github.com/fastai/fastai
cd fastai
tools/run-after-git-clone
pip install -e .[dev]
如果遇到问题,去github上查看相关问题,一般都有解决。
总览
fastai是一个使用了大量的python技巧并且高度紧凑、高度可扩还有良好的编码风格的一个库,总览如下。
图片载自fastai官网,由上图可知,从左到右分别是核心代码、训练代码和应用代码,其中的关系可以由图标很清晰地得到。
fastai源码中部分使用的python技巧(对阅读fastai源码有帮助):
https://docs.python.org/3/library/typing.html
https://julien.danjou.info/guide-python-static-class-abstract-methods/
快速训练
好了,废话不多说,直接进入主题。
我们在训练的时候,往往需要三个部分:
- (预训练)模型
- 数据集加载代码
- 训练代码(包括验证评价标准)
把这三个部分搞定,就可以直接进行训练了:
fastai中的预训练模型
这次fastai提供的模型有Pytorch中自带的模型和fastai自己设计的模型,我们也可以自己设计模型,就像在Pytorch中开发一样。
下载fastai中各种网络模型的权重
fastai使用的深度学习内核是Pytorch,因此fastai中有torchvision中常用的训练好的模型,例如resnet系列、vgg系列以及densenet系列。可以直接拿来使用。
除了torchvision中已经存在的模型fastai也收集了一些我们平时比较常用的模型,例如resnext系列和inception系列,这些系列的预训练模型需要自己单独下载,fastai源码中并没有提供直接下载代码。
fastai已经打包为weights.tgz
。
下载网址:http://files.fast.ai/models/
fastai中读取数据集的方式
fastai中最主要的读取数据集的类为class ImageDataBunch
,通过该类的几个方法去读取不同格式不同任务的数据集。当然fastai最终使用的还是Pytorch中的函数,因此想要了解fastai读取数据的方式,首先对Pytorch的数据读取方式比较熟悉。
我们以图像分类任务来讲解,例如分类猫和狗,猫和狗的图像放在一个文件夹中,然后存在一个csv文件,csv文件存放了图像的名称和对应的标签(例如 图像名称 image_1.jpg 对于标签 dog)。
大概的流程是:
- 读取csv文件,得到train和val相应的namelist和label(也就是图像存放的地址和图像相应的标签)
- 对读取到的label进行处理,比如挑出一共存在几类,为分类定数字标签(比如狗对于0,猫对于1)
- 将读取到的数据制作为dataset类,即可以通过
__getitem__
去索引 - 利用
transform_datasets
包装创建好的dataset
类,对图像进行图像增强技术,可以在训练的时候实时进行图像变化(也包括对图像的尺寸变化) - 最后利用
dataloader
包装transform_datasets
,确定batch_size
和num_workers
,得到train和val的dataloader
类 - 利用
DeviceDataLoader
类将得到的dataloader
类迁移到使用的device
(GPUs or CPU)
最后得到的是包含已经将数据集移动到合适device
中的dataloader
,分别是train_dl
、valid_dl
和test_dl
(可选)和需要使用dataloader
去加载的dataset
。
需要注意的是,在使用ImageDataBunch.from_folder()
去读取训练数据集的时候,必须指定想要训练图像的大小,如果不填写的话会报错(未来这个会改进)。
几个比较重要的数据类:
- Pytorch中的
Dataset
类
# torch/utils/data/dataset.py # Pytorch中的数据类所有的数据都要从这个类中继承 class Dataset(object): """An abstract class representing a Dataset. All other datasets should subclass it. All subclasses should override ``__len__``, that provides the size of the dataset, and ``__getitem__``, supporting integer indexing in range from 0 to len(self) exclusive. """ def __getitem__(self, index): raise NotImplementedError def __len__(self): raise NotImplementedError def __add__(self, other): return ConcatDataset([self, other])
- fastai中的
DatasetBase
类
# fastai/data.py # fastai中的最基本类,继承Pytorch中的基本dataset类 class DatasetBase(Dataset): "Base class for all fastai datasets." def __len__(self): return len(self.x) @property def c(self): "Number of classes expressed by dataset y variable." return self.y.shape[-1] if len(self.y.shape)>1 else 1 def __repr__(self): return f'{type(self).__name__} of len {len(self)}' # fastai中的分类标签类 class LabelDataset(DatasetBase): "Base class for fastai datasets that do classification." @property def c(self): "Number of classes expressed by dataset y variable." return len(self.classes)
- fastai的vision视觉模块中的
ImageDataset
类
# fastai/vision/data.py # 这个类是针对图像数据方面使用,继承了fastai中的基本标签类,实现了getitem功能 class ImageDataset(LabelDataset): "Abstract `Dataset` containing images." def __init__(self, fns:FilePathList, y:np.ndarray): self.x = np.array(fns) self.y = np.array(y) def __getitem__(self,i): return open_image(self.x[i]),self.y[i]
这是最基本的几个类,fastai中的其他数据类都是从以上这几个继承而来,随后通过ImageDataBunch
类进行读取训练。
fastai中的图像增强技术
新版本的fastai提供了比传统图像增强技术更好的算法。
如下面的图像,最左边是原图,中间是使用传统图像增强技术变换后的,而最右边是使用fastai库进行变化的。可以发现最右边的旋转放大(rotate and zoom)后的飞机的窗户仍然可以看出来,而中间图像-变换后飞机的窗户就比较模糊。懂深度学习的同学应该知道数据集好坏对结果的好坏影响还是比较大的。
总之fastai提供了许多自己的图像增强库,可以自己去拓展,当然也可以自己去编写函数实现自己的图像增强方法。
fastai中的训练函数
fastai中的训练代码可以帮助我们短短几行代码就可以快速进行训练,其中实现的逻辑包括了:
- 加载预训练模型,可以选择加载的层数,是否freeze
- 设定训练batch和epoch
- 设定好或者自己传入optimizer
- 可以自己添加callback函数实现在训练过程中的一处理
- 使用fastai提供或者自己设计的验证指标(metrics)
- 最主要还可以使用很多训练tricks,例如
lr_find
和one cycle
训练。
fastai中训练可视化
fastai中训练默认是看不到实时的训练或者验证损失曲线,我们可以利用官方提供的fastprogress可视化,或者利用tensorboardX添加到callback中进行可视化。
以下是通过添加官方提供的可视化方法实现可视化:
callback_fns=ShowGraph
总之,拓展性很强,我们可以自己绑定callback
方法实现自定义的可视化。
后记
当然本篇文章只是对fastai的简介以及如何快速入门,最详细的信息还是建议去查阅官网的最新教程,官方的教程每天都在更新。
另外,TWiML频道对fast.ai的创始人Jeremy Howard进行了一个多小时的采访:The Fastai v1 Deep Learning Framework with Jeremy Howard。如果想了解fastai的幕后工作顺便学一学英语,可以考虑听一听。建议在youtube上观看,因为在官方是没有字幕的,在youbute可以借用youtube的自动英文字幕功能观看采访的字幕,达到学习英语的效果。