Fast.ai 是一个建立在 PyTorch 之上的深度学习库,PyTorch是目前最受欢迎的深度学习框架之一。Fast.ai 利用深度学习中的高级方法和手段来生成最先进的结果。这种方法使能够以更少的数据、时间和金钱训练出更准确的模型。Fast.ai 由 Jeremy Howard 和 Rachel Thomas 创立,旨在为深度学习实践者提供一个快速且简单的方式,在深度学习的标准化监督学习领域(即视觉、文本、表格和协同过滤)中实现最先进的结果。
本教程假设已经具备 Python3 的基本知识。需要一个带有 GPU 的 Jupyter 笔记本,因为 GPU 可以将训练过程的速度提高 100 倍。可以从 Google Colaboratory 访问,这是一个 Jupyter 笔记本环境,并提供免费的 GPU。
训练一个图像分类器
让使用Fast.ai训练一个基本的 MNIST图像分类器。MNIST 数据集包含从 0 到 9 的手写数字图像,因此它有 10 个类别,这是一个多类分类问题。它包含 60000 张训练集图像和 10000 张验证集图像。
导入库
在第一个单元格中,运行以下代码以确保所有必需的库都已安装。如果没有,将安装 fastai 库,需要重新启动运行时。
!pip install fastai --upgrade
然后让导入 fastai 视觉库:
from fastai.vision.all import *
如果有 Python 编程或软件开发的经验,可能会对从类中导入所有子模块和函数(即使用 *) 感到疑惑。但 fastai 库的设计方式是只导入所需的函数,并确保不会对内存造成不必要的负担。
现在,让下载所需的数据:
path = untar_data(URLs.MNIST)
这里使用一个 fastai 函数 untar_data
,它接受数据集的 URL,下载并解压数据集,然后返回数据的路径。它返回一个 Pathlib's PosixPath
对象,可以轻松访问和导航文件系统。从 fastai 的 URLs
方法中获取 MNIST 数据集 URL,其中包含许多不同数据集的 URL。
可以使用 path.ls()
检查路径中的内容。可以看到有两个文件夹 training
和 testing
,分别包含训练数据和验证数据。
加载数据
现在可以加载数据:
dls = ImageDataLoaders.from_folder(path=path, train='training', valid='testing', shuffle=True)
ImageDataLoaders
是用于加载计算机视觉问题数据集的类之一。通常,计算机视觉数据集的结构是这样的:图像的标签是包含图像的文件夹的名称。由于数据集是这种结构,使用 from_folder
方法从给定路径的文件夹中加载图像。
指定从哪里加载图像的路径,指定包含训练和验证数据的文件夹名称,然后初始化 shuffle
为 True,以确保在模型训练时图像被混洗并输入模型。
可以使用 doc()
方法获取任何 fastai 函数的更多信息,它显示了该函数的简要文档。
doc(ImageDataLoaders.from_folder)
可以使用 show_batch()
方法查看一些数据:
dls.train.show_batch()
dls.valid.show_batch()
它分别显示训练集和验证集的一些图像。
模型训练
现在让创建模型:
learn = cnn_learner(dls, resnet18, metrics=[accuracy, error_rate])
这里使用 cnn_learner
,即指定 fastai 构建一个卷积神经网络模型,从给定的架构 resnet18
训练在指定的数据加载器 dls
上,并跟踪提供的指标 accuracy
和 error_rate
。
CNN 是创建计算机视觉模型的当前最先进方法。这里使用一种称为 transfer learning
的技术来训练模型。将在下一节详细讨论。
现在让训练(实际上是微调)模型:
learn.fine_tune(4)
可以看到模型开始在数据上训练 4 个周期。结果如下:
哇!99% 的准确率和几乎 0.8% 的错误率实际上是最先进的结果。只用了 4 个周期、5 行代码和 5 分钟的训练就实现了这一点。
from fastai.vision.all import *
path = untar_data(URLs.MNIST)
dls = ImageDataLoaders.from_folder(path=path, train='training', valid='testing', shuffle=True)
learn = cnn_learner(dls, resnet18, metrics=[accuracy, error_rate])
learn.fine_tune(4)
这是由于一种称为 Transfer Learning
的技术。让详细讨论一下。
迁移学习
在继续之前,应该了解预训练模型。预训练模型基本上是已经在不同数据集和不同目的上训练过的架构。例如,已经使用 resnet18
作为预训练网络。也称为残差网络,resnet18
包含 18 层,并且在 ImageNet 数据集上的一百多万张图像上进行了训练。这个预训练网络可以轻松地将图像分类为 1000 个类别,如书籍、铅笔、动物等。因此,这个模型在训练数据集之前就已经知道各种对象和事物。因此,它被称为预训练网络。
现在迁移学习是一种使能够使用预训练模型进行新任务和数据集的技术。迁移学习基本上是使用预训练模型进行与其最初训练不同的任务的过程,即在这种情况下,使用 resnet18
来训练手写数字图像。
这是由于一个基本步骤称为 fine-tuning
。当有一个预训练模型时,使用这一步根据任务/数据的需求更新预训练模型。微调基本上是一种迁移学习技术,它通过在新数据集上训练几个周期来更新预训练模型的权重。
因此,可以使用这种技术在任务中实现最先进的结果,即分类手写数字。
首先,让获取测试集中的所有图像路径,然后将其转换为图像并进行预测。
# 获取测试文件夹中的所有图像路径
images = get_image_files(path/'testing')
# 选择一个图像并显示
img = PILImage.create(images[4432])
img
# 预测图像类别
lbl, _ , _ = learn.predict(img)
lbl
interep = ClassificationInterpretation.from_learner(learn)
interep.plot_confusion_matrix()