最近,Jeff Leek 在 Simply Stats 上发表了一篇题为「如果你的数据量不够大就不要使用深度学习」(Don't use deep learning your data isn't that big)的文章(链接见文末),认为只有获得了谷歌、Facebook 这样规模的数据才有资格做深度学习。对于这点 Andrew L. Beam(本文作者)并不反对,他认为这使我们清楚地意识到深度学习并不是一种万能的灵药;但是,虽然 Beam 同意其核心观点,但是其还有很多不明确或不清晰的地方,并且 Beam 认为只要小心地训练模型,就能在小数据设置中使用深度学习。机器之心对该文进行了编译,原文链接请见文末。 Jeff Leek 采用两种方法基于 MNIST 数据集对手写字体进行分类。他对比了五层神经网络(激活函数使用的是 hyperbolic tangent)的系统和 Leekasso,Leekasso 仅仅使用了带最小边际 p-value 的 10 块像素。他惊讶地表明,在使用少量样本时,Leekasso 要比神经网络性能更加出色。
难道如果你的样本量小于 100,就因为模型会过拟合并且会得出较差的性能而不能使用深度学习?可能情况就是如此,深度学习模型十分复杂,并且有许多训练的技巧,我总感觉缺乏模型收敛性/复杂度训练也许才是性能较差的原因,而不是过拟合。 深度学习 VS. Leekasso Redux 首先第一件事就是建立一个使用该数据集的深度学习模型,也就是现代版的多层感知机(MLP)和卷积神经网络(CNN)。如果 Leek 的文章是正确的话,那么当只有少量样本时,这些模型应该会产生严重的过拟合。 我们构建了一个激活函数为 RELU 的简单 MLP 和一个像 VGG 那样的卷积模型,然后我们再比较它们和 Leekasso 性能的差异。 所有的代码都可下载:https://github.com/beamandrew/deep_learning_works/blob/master/mnist.py 多层感知机模型是非常标准的:
CNN 模型也和以前的十分相似:
作为参考,MLP 大约有 12 万个参数,而 CNN 大约有 20 万个参数。根据原文的假设,当我们有这么多的参数和少量样本时,模型好像真的会出错。 我们尽可能地靠近原始分析,我们使用了 5 层交叉验证(5-fold cross validation),但使用了标准 MNIST 测试集进行评估(大约有 2000 张测试样本)。我们将测试集分为两部分,上半部分用于评估训练过程的收敛,而下半部分用于测量样本预测的准确度。我们甚至没有调整这些模型,对于大多数超参数,仅仅只是使用合理的默认值。 我们尽可能地重新构建了原文中 Leekasso 和 MLP 的 Python 版本。代码可以在此处下载:https://github.com/beamandrew/deep_learning_works/blob/master/mnist.py 以下是每个模型的样本精度:
这两个模型的精度和原来的分析有很大的不同,原始分析中对小样本使用 MLP 仍然有很差的效果,但我们的神经网络在各种样本大小的情况下都可以达到非常完美的精度。 为什么会这样? 众所周知,深度学习模型的训练往往对细节要求极高,而知道如何「调参」是一件非常重要的技能。许多超参数的调整是非常具体的问题(特别是关于 SGD 的超参数),而错误地调参会导致整个模型的性能大幅度下降。如果你在构建深度学习模型,那么就一定要记住:模型的细节是十分重要的,你需要当心任何看起来像深度学习那样的黑箱模型。 下面是我对原文模型出现问题的猜测: 激活函数是十分重要的,而 tanh 神经网络又难以训练。这也就是为什么激活函数已经大量转而使用类似「RELU」这样的函数。 确保随机梯度下降是收敛的。在原始比较中,模型只训练了 20 个 epoch,这可能是不够的。因为当 n=10 个样本时,20 个 epochs 仅仅只有 20∗10=200 次的梯度迭代更新。而遍历全部的 MNIST 数据集大概相当于 6 万次梯度更新,并且更常见的是遍历数百到数千次(大约百万次梯度更新)。如果我们仅仅执行 200 次梯度更新,那么我们需要比较大的学习率,否则模型就不会收敛。h2o.deeplearning() 的默认学习率是 0.005,这对于少量的更新次数来说太小了。而我们使用的模型需要训练 200 个 epoch,并且在前 50 次 epoch 中,我们能看到样本精度有很大的一个提高。因此我猜测模型不收敛可以解释两者样本精度的巨大差别。 (责任编辑:本港台直播) |