本节课程将针对Kaggle竞赛中的Dogs vs. Cats,利用Fast AI搭建一个图像分类器。视频课程对应的Notebook是lesson1.ipynb中的改变学习速率
及之前的部分。主要内容是:
- 利用Fast AI搭建图片分类网络。
- 如何选择学习速率。
事实上,利用Fast AI搭建网络,然后训练预测,是一件相对简单的事情,简单到只需要三行代码就可实现。
data = ImageClassfierData.from_paths(PATH, tfms=tfms_from_model(arch, sz))
learn = Convlearner.pretrained(arch, data, precompute=True)
learn.fit(0.01, 2)
代码逻辑
看下来代码逻辑也非常清晰:
1. 明确在某数据集上进行训练
-
数据集的路径由变量PATH指定,其目录的组织方式如下:
train valid models test sample
其中train、valid、test分别存放了训练数据、验证数据、测试数据;其下又有各类图片的子目录。models是后续调用learn.save()时模型参数存放的目录。对本例而言train目录下有cats、dogs两个子目录,每个子目录下大致有11500张图片。valid目录下,cats、dogs分别有1000张图片。
上述路径存储方式是一种通用的目录结构,为大多数深度学习框架所支持;另一种方式是以csv文件记录数据形式,将在第二节课中看到。 -
函数参数tfms限定了对数据所做的基本预处理操作,以使得数据满足网络的输入要求。本例中所选网络架构为
arch=resnet34
,输入图像的长宽尺寸均为sz=224
。
2. 构造分类器
-
按照指定的网络架构,根据训练数据,构造分类器。由于本例中采用了在ImageNet数据集上训练好的分类网络,因此采用
pretrained()
方法。这样,只需训练最后的全连接层即可。 -
由于只需训练最后面的全连接层,因此由已有的卷积核参数生成的结果保持不变,所以在此设置
precompute=True
。
3. 开始训练
-
fit函数的第一个参数0.01为深度学习网络的超参数:学习速率,即每次优化损失函数时,沿梯度方向前进的步长。后续课程会给出一个确定初始值的方法。
-
fit函数的第二个参数2,在此可以简单地理解为将遍历数据集两次。该值和后续的一个额外参数
cycle_len
会有关联。
学习速率设定
课程中依据2015年的一篇论文Cyclical Learning Rates for Training Neural Networks,给出了超参数学习速率的选择方法:learn.lr_find()
。方法描述如下:
将学习速率设置为小值,以每一步批量优化为步骤,逐步增大学习速率,直至损失函数不再降低。此时选择损失函数降低速率较大、学习速率也较大的值。
原论文中建议选择使损失函数降低较为陡峭额值作为学习速率,Fast AI的开发者则倾向于选择一个比上述值较大的值,后续课程会解释相关理念。如下图示,原文可能倾向于选择 1 0 − 3 10^{-3} 10−3,Fast AI倾向于选择 1 0 − 2 10^{-2} 10−2。
一些Jupyter Notebook的小技巧
- 按h可显示快捷键提示页面。
- tab:代码补全。
- shift+tab:显示函数提示,按不同次数的tab,可有详细程度不同的提示。
- 在命令前放置?,运行后会显示相关提示;放置??会显示相关函数的源代码。
- !: 用于执行bash命令。