fastai教程学习笔记

这几天对着fastai教程读了下,大部分写得已经很不错。这里做点知识精炼的笔记。

安装fastai

推荐在conda环境内执行以下命令。它

pip install fastai

fastai架构

fastai的编程架构如下图所示:

fastai提供了高、中、低三层的API,用户可以根据自己的需求在合适的层面上开发。用户的需求越定制化,则使用的API越底层。用户对框架越熟悉,其越有能力基于底层的API进行开发。

通过谷歌搜索"fastai xxx"可以搜索API的文档,比如搜索"fastai untar_data",你可以看到untar_data的文档

在高层API的帮助下,fastai能支持对各种领域的问题快速建模,包括计算机视觉(vision)、自然语言处理(text)、表格分析(Tabular)、推荐系统(Collab)。如果想使用中层、底层的API,同样也有提供教程。

fastai导读

首先,分析fastai的目录结构如下图所示。

  • 第一个红框,Quick start。给出了cv、nlp经典问题领域的样例代码,它们都使用了fast高层的API,代码行数只需十几行。
  • 第二个红框,Tutorials。给出了更详尽的代码教程,既包括使用高层API解决各领域问题的教程,也包括基于底层API开发的教程。
  • 第三个红框,Training、Data等等。给出了fast各个模块的接口文档。教程中使用的各种接口,都能在此处找到文档解释。

所以,推荐的阅读顺序是,先把Quick start的notebook运行一下,了解基本用法,再阅读Tutorials的各种教程。所有教程的notebook都可见于fastai/nbs

Tutorials导读

如何阅读Tutorials章节?该章节分为两部分:

  1. 根据难易程度,有Beginner、Intermediate、Advanced三节。
    • Beginner章节给出了cv、text、tabular和collab四个领域问题的代码样例,相较于Quick start更详细一些。
    • Intermediate、Advanced给出了更定制化的代码样例,读者会接触到更底层的API。
  2. 最后Migrating from Other Libs教你从其它框架迁移到fastai。通常只需要阅读pytorch相关的小节。

本章剩余部分会提到一些笔者认为有必要讲解的章节,并进行概括。

Beginner

Computer vision intro

讲解了用fastai解决图像分类和图像分割任务的样例代码。

Text transfer learning

该例子用了以下迁移学习流程。

  1. 将模型在wiki词库作next-word prediction训练。笔者认为这样能让模型能学习英语语法。
  2. 将上一步的模型迁移到IMDb上作next-word prediction训练。笔者认为这样能让模型学习影评的语言风格。
  3. 最后将上一步的模型迁移到IMDb作分类训练。

Intermediate

Data block tutorial

首先,第一节Building a DataBlock from scratch讲解了如何从零开始构建Datablock。首先构建一个空的Datablock,再根据任务需要逐步为其添加参数,最终令其能够适应于图像分类任务。

剩下几节会讲解在Image classification、Image localization、Text、Tabular data四个场景下,Datablock是怎样构建的。

Training Imagenette

  1. 第一节Assemble the data教你用三种方式构建DataLoaders:直接构建、基于DataBlock构建、或者基于Dataset构建。
  2. 第二节Training教你如何根据需求定制学习器Learner,比如修改loss函数、修改optimizer、新建一个Callback。

第一节提到了,你有三种方法创建DataLoaders:

  1. 利用API直接创建DataLoaders,比如ImageDataLoaders.from_folder
  2. 利用API先创建DataBlock,再创建DataLoaders。
  3. 利用中层API先创建Dataset,再创建DataLoaders。

fastai的基本使用范式

一个最简单的例子如下所示:

  1. 创建数据源DataLoaders
  2. 将其喂给Learner,调用拟合方法,在期间会完成训练和验证任务。
    训练完成后,你可以调用predict方法。
from fastai.vision.all import *

path = untar_data(URLs.PETS)
def label_func(f): return f[0].isupper()
dls = ImageDataLoaders.from_name_func(path, files, label_func, item_tfms=Resize(224))

learn = vision_learner(dls, resnet34, metrics=error_rate)
learn.fine_tune(1)

训练好后,学习器可以用来预测任务:

learn.predict(files[0])

也可以观察实验结果,查看模型对某些样本预测的情况:

learn.show_results()

还可以观察可解释性,查看造成最多损失的样本:

interp = Interpretation.from_learner(learn)
interp.plot_top_losses(9, figsize=(15,10))

一个基本的fast应用中,只需要由DataLoaders和Learner组成,前者是数据源,后者是学习器。DataLoaders定义了数据的格式,Learner负责训练、验证、预测。
总而言之,fastai简化了神经网络训练流程的代码编写,在最简情况下,将一个DataLoaders赋给Learner就可以训练了。

fastai 部分接口理解

数据源接口 DataLoaders和DataBlock

作为Learner的数据源,DataLoaders通常是将属性path赋予DataBlock创建,path给出了数据样本的位置(比如图片的路径)。DataBlock应当有以下能力:

  • 如何找到样本,这与属性get_items有关。
  • 装配了训练集和验证集(比如定义了训练集、验证集的切割方式),这与属性splitter有关
  • 能够取得样本的特征x和标签y,这与属性blocksget_yget_x有关
  • 还可以定义预处理行为,这与属性item_tfmsbatch_tfms有关。

所以,当DataBlock创建了DataLoaders后,各个属性在fastai内部作用的顺序应当如下

  1. 首先,根据get_iitems找到了样本集合,包括训练集和验证集。比如可以是所有图片的路径名。
  2. 然后,根据splitter切割训练/验证集。splitter能够判断一个样本是属于训练集还是属于验证集。
  3. 对于每个样本,根据get_xblocks[0]得到输入,根据get_yblocks[1]得到标签。
  4. 输入在喂给模型前,依次用item_tfmsbatch_tfms作数据预处理。

你可以先创建DataBlock,再由它创建一个DataLoader。Datablock相当于一个模具,定义了如何理解数据的方式。而为Datablock传入数据源后,就能得到DataLoaders,可以用于加载数据了。DataBlock的具体用法,建议阅读tutorial.imagenette,从一个空白DataBlock不断填充属性,定义其行为,最终得到能正确处理数据的DataBlock。

以下几个概念具有包含关系

  • 一个DataBlock可以由多个Block组成。
  • 一个DataLoader可以由DataBlock得到。

数据预处理接口 Item_tfms vs batch_tfms

参考Item_tfms vs batch_tfms可知,所有图片会先各自按照Item_tfms在CPU处理,再送入GPU按照batch_tfms处理。

Because we can separate how each one works and where it’s applied. In fastai v1 everything was CPU bound as well.
Again, two seperate ones are needed because the item transforms are all done on the CPU and batch are all on the GPU
And we need these CPU-bound item transforms so everything can be put into a batch and be allowed to be pushed to the GPU

learn.lr_find

会显示loss随学习率变化的曲线,比如下图所示。详细用法参考fastai-lesson-1-image-classification-下篇-aab0ea73570a

fastai vs 原生pytorch

fastai对比pytorch的进步

个人觉得,fastai最大的价值在于

  1. 简化了训练过程:
    • 包装了learner.fit_one_cycle方法,可以自动完成多轮训练。
    • 包装了learner.fine_tune方法,用户可以很方便地作迁移学习,比如从一个训练好的resnet迁移到新的小数据集上。
  2. 提供了训练效果回顾工具:
    • 包装了learn.lr_find()方法,用户可以找到最佳的学习率范围。
    • 包装了learn.show_results()方法,可以快速查看预测结果。
    • 提供了Interpretation类,后者包装了interp.plot_top_lossesinterp.top_losses方法,可以查看模型最差表现的样例。提供了show_results()方法,可以查看模型表现。

但是它也有局限性:

  1. 其提供的数据读取接口DataLoaders等等,完全可以被更简单的原生pytorch的Dataloader和collate_fn取代
  2. 其提供的数据集接口untar_data、URLs.IMDB等等,完全可以被torchvision和hugginface取代

如何从pytorch迁移到fastai

可参考Pure PyTorch to fastai,详细版在Pytorch to fastai details

总而言之,你可以将任意一个环节替换为原生pytorch,并组装到fastai流程中。文档讲解了如何将数据源、模型、optimizer替换为原生pytorch。

pytorch与fastai的结合怎样实践最好?这里笔者推荐将数据源用原生pytorch替代,但复用fastai的Learner。具体做法是,在创建数据源DataLoaders时,用原生pytorch的DataLoader组装。

from torchvision import datasets
from torch.utils.data import DataLoader
from torchvision.transforms import transforms

tfms = transforms.Compose([transforms.ToTensor(),
                                 transforms.Normalize((0.1307,), (0.3081))
])

train_dset = datasets.MNIST('../data', train=True, download=True, transform=tfms)
valid_dset = datasets.MNIST('../data', train=False, transform=tfms)


train_loader = DataLoader(train_dset, batch_size=1,
                          shuffle=True, pin_memory=True)

test_loader = DataLoader(valid_dset, batch_size=1,
                         shuffle=False, pin_memory=True)

from fastai.data.core import DataLoaders
dls = DataLoaders(train_loader, test_loader)
for x, y in dls.train:
    print(x.shape, y.shape)
    break

for x, y in dls.valid:
    print(x.shape, y.shape)
    break

输出如下:

torch.Size([1, 1, 28, 28]) torch.Size([1])
torch.Size([1, 1, 28, 28]) torch.Size([1])

可见,DataLoaders的用法是通俗易懂的,通过.train.valid可以获取训练/验证集,然后for循环能遍历每个样本的特征和标签。
之后把dls组装到Learner时,只需注意让Net的输出能与y尽量匹配即可。你同样可以自定义loss_func来定制损失计算的需求。

learn = Learner(dls, Net(), loss_func=F.nll_loss, opt_func=opt_func, metrics=accuracy)

总结

fastai最大的贡献还是在于节省了你写train、val方法的冗杂步骤。Learner的包装还是很简洁的,但DataBlock的包装简直是依托答辩,没有人会有耐心学习你那些get_xget_items属性的,有这功夫我用原生的DataLoader组装就完事了。

建议用原生pytorch的DataLoader组装DataLoaders,然后配合Learner使用。

延伸阅读Walk with fastai

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值