将 Lightning 与 fastai 结合使用

将 fastai 的优点渐进式地添加到您的 Lightning 训练中

我们将使用 Lightning ‘快速入门’ 中的 MNIST 训练代码(截至 2020 年 8 月),并将其转换为一个模块。

注意

如果您从 git 克隆了 fastai 仓库,migrating_lightning 的源脚本位于此文件夹的 examples 子目录中;如果您使用 Colab 等在线查看器,则可以从此处下载。

from migrating_lightning import *

from fastai.vision.all import *

使用 fastai 的训练循环

我们可以直接使用 Lightning 模块

model = LitModel()

要在 fastai 中使用它,我们首先将模块中的 DataLoaders 提取到一个 DataLoaders 对象中

data = DataLoaders(model.train_dataloader(), model.val_dataloader()).cuda()

现在我们可以创建一个 Learner 并进行拟合

learn = Learner(data, model, loss_func=F.cross_entropy, opt_func=Adam, metrics=accuracy)
learn.fit_one_cycle(1, 0.001)
epoch 训练损失 验证损失 准确率 时间
0 0.367197 0.333293 0.910800 00:11

正如您所见,从 Lightning 迁移使我们能够减少代码量,并且不需要更改任何现有的数据管道、优化器、损失函数、模型等。完成此更改后,您就可以受益于 fastai 丰富的回调函数、转换、可视化等功能。

例如,在 Lightning 示例中,Tensorboard 支持被定义为一个特殊的“记录器”(logger)。在 fastai 中,Tensorboard 只是您可以添加的另一种回调函数(Callback),在创建 Learner 时,使用参数 cbs=Tensorboard 即可。所有回调函数都可以协同工作,因此您可以添加或移除任何调度器、记录器、可视化器等。您无需了解每种特殊功能类型——它们都只是普通的回调函数。

请注意,fastai 与 Lightning 非常不同,它不仅仅是一个训练循环(尽管在此示例中我们只使用了训练循环)——它是一个完整的框架,包括 GPU 加速的转换、端到端推理、集成的计算机视觉、文本、表格数据和协同过滤应用等。您可以单独使用框架的任何部分,也可以将它们组合起来,如fastai 论文中所述。

利用 fastai 数据块

Lightning 示例中的一个问题是它并没有实际使用验证集——它只是第二次将训练集用作验证集。

您可能更喜欢使用 fastai 的 Data Block API,它使创建、可视化和测试输入数据处理变得非常容易。例如,您可以通过以下方式创建 MNIST 的输入数据

mnist = DataBlock(blocks=(ImageBlock(cls=PILImageBW), CategoryBlock), 
                  get_items=get_image_files, 
                  splitter=GrandparentSplitter(),
                  get_y=parent_label)

在这里,我们告诉 DataBlock 我们有一个黑白图像输入和一个类别输出,我们的输入项是图像的文件名,图像根据父文件夹的名称进行标注,并根据祖父文件夹的名称按训练集与验证集进行分割。实际查看您的数据非常重要,因此 fastai 也使得可视化输入和输出变得容易,例如

dls = mnist.dataloaders(untar_data(URLs.MNIST_TINY))
dls.show_batch(max_n=9, figsize=(4,4))