简洁和效率,我们都要。
通过咱们之前几篇 fast.ai 深度学习框架介绍,很多读者都认识到了它的威力,并且有效加以了利用。
fast.ai 不仅语法简洁,还包裹了很多实用的数据集与预训练模型,这使得我们在研究和工作中,可以省下大量的时间。
跟着教程跑一遍,你会发现做图像、文本分类,乃至推荐系统,其实是非常简单的事情。
然而,细心的你,可能已经发现了一个问题:
fast.ai 训练数据体验很好;可做起测试集数据推断来,好像并不是那么高效。
教程里面,模型训练并且验证后,推断/预测是这么做的:
如果你只是需要对单个新的数据点做推断,这确实足够了。
但是如果你要推断/预测的是一个集合,包含成千上万条数据,那么该怎么办呢?
你可能会想到,很简单,写个循环不就得了?
从道理上讲,这固然是没错的。
但是你要真是那么实践起来,就会感觉到等待的痛苦了。
因为上面这条语句,实际上效率是很低的。
这就如同你要搬家。理论上无非是把所有要搬的东西,都从A地搬到B地。
但是,你比较一下这两种方式:
方法一,把所有东西装箱打包,然后一箱箱放到车上,车开到B地后,再把箱子一一搬下来。
方法二,找到一样要搬的东西,就放到车上,车开到B地,搬下来。车开回来,再把下一样要搬的东西放上去,车开走……重复这一过程。
你见过谁家是用方法二来搬家的?
它的效率太低了!
用循环来执行 predict 函数,也是一样的。那里面包含了对输入文本的各种预处理,还得调用复杂模型来跑这一条处理后的数据,这些都需要开销/成本。
怎么办?
其实,fast.ai 提供了完整的解决方案。你可以把测试集作为整体进行输入,让模型做推断,然后返回全部的结果。根本就不需要一条条跑循环。
可是,因为这个方式,并没有显式写在教程里面,导致很多人都有类似的疑问。
这篇文章里,我就来为你展示一下,具体该怎么做,才能让 fast.ai 高效批量推断测试集数据。
为了保持简洁,我这里用的是文本分类的例子。其实,因为 fast.ai 的接口逻辑一致,你可以很方便地把它应用到图像分类等其他任务上。
划分为了保持专注,我们这里把一个模型从训练到推断的过程,划分成两个部分。
第一部分,是读取数据、训练、验证。
第二部分,是载入训练好的模型,批量推断测试集。
我把第一部分的代码,存储到了 Github 上,你可以在我的公众号“玉树芝兰”(nkwangshuyi)后台回复“train”,查看完整的代码链接。
点击其中的“Open in Colab”按钮,你可以在 Google Colab 云端环境打开并且执行它,免费使用 Google 提供的高性能 GPU 。
如果你想了解其中每一条代码的具体含义,可以参考我的这篇《如何用 Python 和深度迁移学习做文本分类?》。
注意,在其中,我加入了3条额外的数据输出语句。
分别是:
data_clas.save('data_clas_export.pkl')这一条,存储了我们的分类数据(包含训练集、验证集、测试集)及其对应的标签。注意,因为 fast.ai 的特殊假设(具体见后文“解释”部分),测试集的标签全部都是0。
也正因如此,我们需要单独存储测试集的正确标签:
with open(path/"test_labels.pkl", 'wb') as f: pickle.dump(test.label, f)除了上述两条之外,你还需要保留训练好的模型。
毕竟,为了训练它,我们也着实是花了一番时间的。
learn.export("model_trained.pkl")上述 pickle 数据文件,我都存储到了 Gitlab 公共空间。后面咱们要用到。
这就是训练和存储模型的全部工作了。
第二部分,才是本文的重点。
这一部分,我们开启一个全新的 Google Colab 笔记本,读入上述三个文件,并且对测试集进行批量推断。
这个笔记本,我同样在 Github 上存储了一份。