快速 AI 拉动一个快速的 AI?

Fast AI pulling a fast one?

通常像 from module import * 这样的语句会被专家 python 程序员所反对,因为它们会导致命名空间破坏。然而,它们在 Fast AI 中很常见,理由是它让学生的生活更简单。以下是摘自 their book

可能是这样,我想只要简单地导入所有内容就可以了。

然而,下面我们将看到它做的不仅仅是一个简单的导入和一个 cnn_learner 的实例,它没有名为 fine_tune 的方法,当我们 运行来自 fastai.vision.all import *.

from torch import tensor
import numpy as np

from fastai.data.block import DataBlock, CategoryBlock
from fastai.vision.learner import cnn_learner

from torchvision.models.resnet import resnet18

images=tensor(np.random.normal(size=(32,128,128,3)))
labels=tensor(np.random.randint(0,3,32))

data=[{'x':x,'y':y } for (x,y) in zip(images,labels)]

db=DataBlock(blocks=(DataBlock, CategoryBlock),get_x=lambda x:x['x'],get_y=lambda x:x['y'])

learner=cnn_learner(db.dataloaders(data),resnet18)

print(hasattr(learner,'fine_tune'))

from fastai.vision.all import *

print(hasattr(learner,'fine_tune'))

第一个打印语句打印 False,第二个打印语句 True,表明导入语句 from fastai.vision.all import *cnn_learner 的实例创建了绑定方法。

我还没有弄清楚它是如何发生的,我相信如果有足够的时间我会弄清楚的。我同样确定无法弄清楚的是,为什么 Fast AI 代码的编写方式需要这样的全局导入来进行简单的训练。

问题:说了这么多,我想知道的是如何让 cnn_learner 进入正确的状态(所有必要的方法)而不像 Fast AI 人员那样进行全局导入?

from fastai.vision.all import * 的另一种方法是

In [2]: import fastai.vision.all as fai

In [3]: print(hasattr(learner,'fine_tune'))
True

第二种方法是导入微调:

In [2]: from fastai.callback.schedule import fine_tune

In [3]: print(hasattr(learner,'fine_tune'))
True

我相信这两种方法中的任何一种都有效,因为 fine_tune 方法在导入 Learner 对象时被猴子修补了。这似乎是 design pattern that the authors prefered 构建 python 库的更标准方法。