最近在跟网上一个比较火的课程《Practical DL for Coders》,由原 Kaggle 排名第一的 Jeremy Howard 讲授,很值得学习,在此推荐一下。

由于这门课程的实践主要是在 AWS 上的 GPU 中进行,所以课程中有一半时间在教授大家关于部署相关的内容,如 ssh, jupyter, tmux 等,这里跳过。另外,这次课程的数据是 Kaggle 上猫狗识别的题目,如果觉得 Kaggle 上下载数据很慢,可以在这里下载,速度会快很多。

在机器学习的问题中,最重要的是数据,没有数据,再精巧的算法也等于零。而拿到数据后,一般需要考虑对数据集进行划分,按二八原则划分为训练集与验证集,另外 Kaggle 上一般还会有一个测试集。

  • 训练集
  • 验证集:验证我们的算法泛化能力如何,同时可以用于指导调参
  • 测试集

由于涉及到的训练数据可能会非常大,所以这里推荐使用 keras 的 ImageDataGenerator 进行按需加载数据,从而避免一次把所有数据全都加载到内存中。ImageDataGenerator 这个模块本身,提供了从已有 numpy 数据中加载(generator.flow(X, y)),也可从文件夹中自动加载(generator.flow_from_directory)。这里,由于后面需调用 flow_from_directory 这个方法,所以数据的目录结构需要事先调整好。即不同类别放在不同的目录中,这样 Keras 会自动初始化我们的输入数据。当然,为了提高我们代码运行的速度,可以在最开始选择数据中的子集进行训练调参,等到算法 OK 的情况下再放到完整数据集上运行。

1
2
3
4
5
6
7
├── data
│   ├── train
│   │   ├── cats
│   │   └── dogs
│   └── valid
│   ├── cats
│   └── dogs

从头开始训练的话,一方面耗时,另一方面训练数据有限,我们的结果可能也不尽人意。更为广泛的是使用一个已经训练好的模型进行初始化,如这次使用的是知名的 VGG 模型,是 2014 年 ImageNet 冠军所训练的模型,利用这个已经训练好的模型好处在于,这个模型中已经有学习到一些复杂的特征,问题初始化就可以考虑得少很多。当然,也可以考虑使用更复杂的 GoogleLeNet,ResNet 等。

1
2
3
4
5
6
7
8
9
10
11
12
# As large as you can, but no larger than 64 is recommended.
# If you have an older or cheaper GPU, you'll run out of memory, so will have to decrease this.
batch_size=64
# Import our class, and instantiate
from vgg16 import Vgg16
vgg = Vgg16()
batches = vgg.get_batches(path+'train', batch_size=batch_size)
val_batches = vgg.get_batches(path+'valid', batch_size=batch_size*2)
vgg.finetune(batches)
vgg.fit(batches, val_batches, nb_epoch=1)

那么,关键的地方在于,vgg16.py 里面到底做了哪些事情呢?

vgg16.py