人人都能懂的机器学习——用Keras搭建人工神经网络10
隐藏层数量
对于很多问题,我们可以从一个隐藏层开始,并得到一个合理的结果。理论上,只有一个隐藏层的MLP也可以模拟最复杂的功能,只要有足够多的神经元。但对于复杂问题而言,深度网络的参数效率比浅层网络要高得多:深度网络使用比浅层网络少指数级的神经元来搭建复杂的功能,并且用相同数量的训练数据实现更好的性能。
为了理解上面所述的现象,我们打个比方。假设我们用绘图软件绘制一片森林,但是禁止复制粘贴。那么就需要单独画出每棵树,一根接一根树枝,一片接一片叶子。但是如果允许复制粘贴,那么我们就可以先画一片叶子,然后复制粘贴来画一根树枝,然后复制粘贴这根树枝来画一棵树,最后复制这棵树来画一片森林。真实世界的数据通常是以这种层次结构来组织的,深度神经网络自动利用了这个事实:底层隐藏层对底层结构建模(比如各种形状和方向的线段),中间隐藏层对底层结构组合而成的中间层结构进行建模(比如正方形,圆形),顶层隐藏层与输出层将中间层结构组合形成高层结构(比如面)。
这种层次结构不仅有助于DNN更快收敛到一个好的结果,它还提高了神经网络泛化到新数据集的能力。比如如果我们已经训练了一个模型用来识别图片中的人脸,现在需要训练一个新的神经网络来识别发型,那么可以通过重用第一个神经网络的底层隐藏层来开始训练。这样我们就不再需要将新神经网络前几层的权值和偏差随机初始化了,而是将前几层的权值和偏差初始化为第一个神经网络的权值和偏差值。这样,网络就不必从头开始学习大多数图片中出现的所有底层结构,它只需要学习更高级的结构即可(比如发型)。这就叫做迁移学习。
总之,对于许多问题,你可以从一个或者两个隐藏层开始,这样神经网络就可以开始工作。比如,仅仅使用一个包含数百个神经元的隐藏层,就可以轻松在MNIST数据集上达到97%以上的准确率;而保持神经元总数不变,增加到两个隐藏层时,就可以达到98%以上的准确率。对于更加复杂的问题时,你可以增加隐藏层的数量,直到开始过拟合。而对于非常复杂的问题,比如大图像的分类或语音识别,通常需要几十层的网络(甚至几百层,但并不是全连接的),并且需要大量的训练数据。我们很少需要从零开始训练这样的网络:通常我们可以重用预先训练好的网络的一部分,这样训练会快得多,需要的数据也会少得多。
每个隐藏层神经元数量
输入层和输出层神经元的数量是由输出形状和输出任务需求决定的。比如MNIST任务需要28*28 = 784个输入神经元以及10个输出神经元。
至于隐藏层的神经元数量,过去常常把它们按大小排列成一个金字塔,每一层的神经元越来越少。这个结构的基本原理是许多底层的特征可以合并成较少的高层特征。比如一个典型的MNIST神经网络可能有三个隐藏层,第一个由300个神经元,第二个有200个,第三个有100个。然而,这种做法在很大程度上已经被放弃了,因为在所有隐藏层中使用相同数量的神经元在大多数情况下表现得一样好,甚至更好。另外,还有一个超参数需要调优,那就是有时根据数据集的不同,我们需要把第一个隐藏层的数量调整得比其他层的都大。
就像隐藏层数量一样,你可以尝试逐渐增加神经元的数量,直到神经网络开始过拟合。但在实践中,选择一个比实际需要的隐藏层和神经元数量更多的模型,然后使用早停或者其他正则化技术来防止过拟合,通常是更简单和更有效的方法。一个谷歌科学家Vincent Vanhoucke将这种方法称为‘弹力裤’:与其浪费时间寻找与你的尺寸完全匹配的裤子,不如找一条可以收缩到合适尺寸的大号弹力裤。使用这种方法,可以避免可能破坏模型性能的瓶颈层出现。另一方面,如果一个层的神经元太少,它就没有足够的表达能力来保存输入的所有有用的信息(比如,一个有两个神经元的层只能输出二维数据,因此如果用它来处理三维数据,就会丢失一些信息)。那么无论网络的其他部分有多么强大,这些信息也永远无法恢复了。
一般来说,增加隐藏层的数量比增加神经元数量的好处更多。
学习率,批次大小以及其他超参数
在MLP中,不只是隐藏层和神经元数量需要调优,这里还有很多其他重要的超参数。虽然我们在未来的文章中还会详细地讲述如何选择超参数,不过这里有一些简单的超参数的设置建议:
- 学习率可以说是最重要的超参数。一般来说,最佳的学习率是最大学习率的一半(也就是大于这个学习率时,训练将会发散)。一个找到合适的学习率的方法是,将一个模型迭代训练几百次,并将学习率从一个很小的值逐渐增加到一个很大的值(比如从10^-5^到10)。通过在每次迭代中将学习率乘以一个常数因子就可以达到上述的目的,(例如,乘以exp(log(10^6^)/500),那么在500次迭代中从10^-5^增加到10。如果将损失作为学习率的函数(使用学习率的对数),那么就可以看到函数一开始下降,但是之后学习率会过大,那么损失会突然上涨:那么最优学习率将比损失开始回升的那一点略低(通常比转折点低10倍左右)。接下来你可以将你的模型初始化,然后使用这个合适的学习率正常进行训练。
- 选择一个比普通小批次梯度下降更好的优化器(并且调优它的超参数)也是非常重要的。这部分我们放在未来的文章中详细阐述。
- 批处理大小也会对模型的性能和训练时间产生巨大的影响。使用大批处理的主要好处是,像gpu这样的硬件加速器可以高效地处理它们,所以训练算法每秒会通过更多的实例。因此,许多研究人员建议使用显存可以容纳的最大批处理大小。但是,这种方法存在一个问题:在实践中,大的批处理大小通常会导致训练的不稳定性,特别是在训练刚开始的阶段,并且训练得到的模型可能不能像小批处理大小的模型那样泛化。Yann LeCun在2018年4月在推特上写道:“真正的朋友不会让朋友用大于32个的批处理。”并且引用了Dominic Masters和Carlo Luschi在2018年的论文中的结论,使用小批处理的方法(2到32)更好,因为小批处理会让模型在更少的训练时间得到更好的性能。但也有其他论文持相反意见:Elad Hoffer等于2017年发表的论文和Priya Goyal等于2017年的论文显示,使用非常大的批处理大小(直到8192个)是可能的,但需要使用各种各样的技术,比如学习率热身(即一开始使用很小的学习率寻来你,然后再逐渐提高)。这使得训练时间会很短,并且没有任何泛化的差距。因此,一种策略是尝试使用一个大的批处理大小,并且使用学习率热身;如果训练不稳定或最终模型性能不理想,那就尝试使用一个小的批处理大小。
- 激活函数的选择已经在之前的文章中提到过了,一般来说ReLU激活函数对于所有的隐藏层都是很好的默认选项。而对于输出层激活函数的选择则取决于任务需要。
- 训练迭代的次数一般不需要进行调整,如果需要的话使用早停就行了。
最佳学习率也会受其他超参数的影响,特别是批次大小。所以在调整了其他超参数后,记得更新学习率。
有关优化神经网络超参数的更多实践例子,请参阅Leslie Smith于2018年发表的论文:《A disciplined approach to neural network hyper-parameters: Part 1 -- learning rate, batch size, momentum, and weight decay》
至此我们对人工神经网络的介绍以及在Keras中的实现已经全部结束了。接下来我们将讨论如何训练非常深的神经网络,如何使用TensorFlowde低层API来自定义模型,以及如何使用Data API来高效地加载和预处理数据。我们还将深入研究其他流行的神经网络结构:用于图像处理的卷积神经网络,用于顺序结构数据的循环神经网络,用于表示学习的自编码器以及生成数据的生成对抗网络。
敬请期待吧!