fastai — 三行代码做迁移学习
是什么
fastai 是一个深度学习训练库,建在 pytorch 上面。
日常类比:PyTorch 像”自己用乐高搭车”——零件齐、灵活,但要花时间。fastai 像”已经搭好底盘、轮子、引擎的半成品车”——你只填颜色和品牌就能开。
最出名的口号是”三行代码 SOTA”——下面三行真的能在猫狗分类上做出接近最好水平的结果:
from fastai.vision.all import *dls = ImageDataLoaders.from_folder(path, valid_pct=0.2, item_tfms=Resize(224))learn = vision_learner(dls, resnet34, metrics=error_rate)learn.fine_tune(3)它由 Jeremy Howard 和 Rachel Thomas 主导,配套有一门叫 Practical Deep Learning for Coders 的免费课,号称”教过 500 万人”。
为什么重要
不理解 fastai 思路,下面这些事都没法解释:
- 为什么 2018 年之后迁移学习(拿 ImageNet 预训练模型微调)变成默认套路——fastai 把它包成一行
fine_tune(3) - 为什么很多 Kaggle 选手第一版 baseline 用 fastai 跑——开箱就是接近 SOTA 的超参
- 为什么”自顶向下教学”(先跑出 SOTA 再讲数学)成为深度学习教学的主流——fast.ai 课程把这套打法做成范式
- 为什么很多 PyTorch 用户读完 fastai 源码后才理解:训练循环里到底哪些套路是研究套路、哪些是工程套路
核心要点
fastai 的设计可以概括成 分层 API(Layered API)——给不同水平的人不同的接口:
-
高层 API:
vision_learner/text_classifier_learner/tabular_learner——一行就能搞定 90% 任务。新手第一周用这个。 -
中层 API:
DataBlock(数据管线声明式 DSL)、Callback(训练循环钩子)、Learner(训练器)——做”标准任务的小变种”用这个。 -
低层 API:
Tensor子类、类型分发(type dispatch)、Transform类——做研究、写新算法用这个。
第二层的两个关键发明:
- DataBlock API:把数据管线写成”声明”——
blocks=(ImageBlock, CategoryBlock)、get_items=get_image_files、splitter=RandomSplitter()、item_tfms=Resize(224)。读起来像填表,不像写代码。 - Callback 系统:训练循环里有 ~20 个挂钩点(
before_fit、after_batch、after_epoch…),所有”花式训练技巧”(mixup、混合精度、early stopping)都写成 Callback 插进去。
第三个关键发明是 fine_tune(epochs) 一招:自动 freeze 主干 → 只训练 head → 解冻 → 用判别式学习率(discriminative LR,深层小、浅层更小)继续训。背后是论文 ULMFiT 的迁移学习配方。
实践案例
案例 1:DataBlock 声明式数据管线
dblock = DataBlock( blocks=(ImageBlock, CategoryBlock), get_items=get_image_files, splitter=RandomSplitter(valid_pct=0.2), get_y=parent_label, item_tfms=Resize(224), batch_tfms=aug_transforms())dls = dblock.dataloaders(path, bs=64)读法:
blocks=(ImageBlock, CategoryBlock)—— 输入图片、输出类别splitter=RandomSplitter(valid_pct=0.2)—— 20% 当验证集item_tfms是”每张图单独处理”(resize),batch_tfms是”整批一起处理”(数据增强,跑在 GPU 上)
整个过程没写一行 for 循环。和 pytorch 原生那套(自己写 Dataset + DataLoader)相比,省了 30 行模板代码。
案例 2:fine_tune 一行迁移学习
learn = vision_learner(dls, resnet34, metrics=accuracy)learn.fine_tune(epochs=3, base_lr=2e-3)fine_tune 内部做了:
- 冻结 ResNet34 的卷积层(只 head 可训)
- 跑 1 个 epoch,让 head 大致就位
- 解冻所有层
- 跑剩下 2 个 epoch,但底层用
base_lr/100、顶层用base_lr——浅层(边缘检测)几乎不动,深层(语义特征)调多点
如果直接 PyTorch 写,要手动写 param_group 配学习率、写两段训练循环、调度学习率——~50 行。fastai 一行。
案例 3:Callback 加新功能
class PrintGradNormCallback(Callback): def after_backward(self): total = sum(p.grad.norm().item() for p in self.model.parameters() if p.grad is not None) print(f"grad norm = {total:.4f}")
learn.fit(3, cbs=[PrintGradNormCallback()])Callback 系统让你在不改训练循环代码的前提下注入逻辑——这是和 pytorch-lightning 的 LightningModule.training_step 不一样的设计:PL 让你重写方法,fastai 让你挂钩。
踩过的坑
-
抽象太重,调参时不知道改哪一颗螺丝:
fine_tune内部封了 freeze、unfreeze、判别式 LR、1cycle 调度——结果不好时新手不知道动哪个。建议读 fastai 源码Learner.fine_tune一次。 -
Callback 顺序有坑:自己写的 Callback 如果改了梯度,可能和内置的
MixedPrecision冲突。order属性控制执行顺序,调错了就静默错。 -
PyTorch 教程不能直接搬:很多 PyTorch tutorial 假设你手写
for batch in dataloader循环;fastai 期望Learner形态,要把代码改成 fastai 风格。 -
文档和源码偶尔不同步:fastai 用 nbdev 写——源码就是 Jupyter notebook。看官网 doc 不够,要去 GitHub 翻
nbs/目录的 notebook。
适用 vs 不适用场景
适用:
- 学习深度学习的入门工具——配套课程是免费且高质量的,远超读论文起步
- 标准任务的 baseline——图像分类、文本分类、表格回归,三行起步看效果
- Kaggle 比赛 baseline——开箱接近最优超参
不适用:
- 自定义研究算法(新 loss / 新优化器 / 新训练策略)——抽象会挡路,不如直接 PyTorch
- 大规模分布式训练——这是 pytorch-lightning 的强项(多 GPU / TPU 配置更成熟)
- 经典机器学习(树模型、SVM、线性模型)——用 scikit-learn,fastai 主要做深度学习
学到什么
- “好默认值”比”灵活”更重要——fastai 把研究界沉淀的最佳实践(1cycle、判别式 LR、mixup)做成默认,新手不用懂也能拿到不错结果
- 分层 API 是教学神器——同一套库,新手用高层、研究员用低层,不必换工具栈
- 声明式数据管线——DataBlock 把”图片从哪来、怎么切、怎么变换”写成声明而非过程,读起来像填表
- 抽象的代价:抽象越多,“出问题时不知道动哪里”的风险越大;做选择时要权衡
延伸阅读
- 课程:Practical Deep Learning for Coders —— 免费、自顶向下、第一节就让你训出 SOTA
- 论文:fastai: A Layered API for Deep Learning —— Howard & Gugger, Information 2020,讲设计哲学
- 书:《Deep Learning for Coders with fastai and PyTorch》(Howard & Gugger)—— 课程的纸质版,500+ 页
- pytorch —— fastai 建在它之上,用 PyTorch 张量和 autograd
- pytorch-lightning —— 同位竞品,工程派;和 fastai 的”教学派”是两条路
- scikit-learn —— 经典 ML 的”好默认”哲学始祖,fastai 在深度学习领域复刻了这套思路
关联
- pytorch —— fastai 的底座;fastai 不重写张量和 autograd,只在训练循环和数据管线层加抽象
- pytorch-lightning —— 同样是 PyTorch 上层,但走”工程”路线(多 GPU / 日志 / 不预设超参);fastai 走”教学 + 默认最佳实践”路线
- scikit-learn —— 经典 ML 的事实标准,fastai 在深度学习领域学了它的”
fit/predict一致接口”和”好默认”思路
一句话定位
PyTorch 给你积木,fastai 给你已经搭好的车——想自己改装就拆开看,不想改装就直接开。三者放一起:scikit-learn 是经典 ML 的”好默认”始祖;pytorch 是深度学习的乐高底座;fastai 是把研究界沉淀的最佳实践打包给入门者的”半成品车”;pytorch-lightning 是给工程团队的”装配线”。选哪个看你处在学习曲线的哪一段。