4. 多层感知机
多层感知机
多层感知机模型除了输入层和输出层, 它中间会有多个隐藏层, 看上去是许多个全连接层堆叠在一起; 这个构造的产生是因为线性模型可能会出错, 因为线性意味着单调, 但是有很多事情是违反单调性的, eg: 银行发放贷款时会评估对方偿还贷款的可能性, 一般来说工资越多, 偿还贷款的可能性就越大, 但是对于工资从0涨到5w的人比1000w涨到1005w的人更容易偿还贷款, 这就违反了单调性;
所以我们会在隐藏层中使用非线性的激活函数来增加整个模型的非线性因素 eg:ReLU函数, sigmoid函数, tanh函数;
K折交叉验证
当我们训练模型时, 我们试图找到一个能够尽可能拟合训练数据的函数; 但是如果它执行地"太好了", 而不能对看不见的数据做到很好泛化, 就会导致过拟合; 当我们有简单的模型和大量的数据时, 我们期望泛化误差与训练误差相近; 当我们有更复杂的模型和更少的样本时, 我们预计训练误差会下降, 但泛化误差会增大;
原则上, 在我们确定所有的超参数之前, 我们不希望用到测试集; 如果我们在模型选择过程中使用测试数据, 可能会有过拟合测试数据的风险, 那就麻烦大了; 如果我们过拟合了训练数据, 还可以在测试数据上的评估来判断过拟合; 但是如果我们过拟合了测试数据, 我们又该怎么知道呢?因此, 我们决不能依靠测试数据进行模型选择; 然而, 我们也不能仅仅依靠训练数据来选择模型, 因为我们无法估计训练数据的泛化误差; 解决此问题的常见做法是将我们的数据分成三份, 除了训练和测试数据集之外, 还增加一个验证数据集(validation dataset), 也叫验证集(validation set);
当训练数据稀缺时, 我们甚至可能无法提供足够的数据来构成一个合适的验证集; 这个问题的一个流行的解决方案是采用K折交叉验证; 这里, 原始训练数据被分成K个不重叠的子集; 然后执行K次模型训练和验证, 每次在K-1个子集上进行训练, 并在剩余的一个子集(在该轮中没有用于训练的子集)上进行验证; 最后, 通过对K次实验的结果取平均来估计训练和验证误差;
欠拟合和过拟合
训练误差(training error)是指模型在训练数据集上计算得到的误差; 泛化误差(generalization error)是指模型应用在同样从原始样本的分布中抽取的无限多数据样本时, 模型误差的期望; 假设一个大学生正在努力准备期末考试; 一个勤奋的学生会努力做好练习, 并利用往年的考试题目来测试自己的能力; 尽管如此, 在过去的考试题目上取得好成绩并不能保证他会在真正考试时发挥出色; 例如, 学生可能试图通过死记硬背考题的答案来做准备; 他甚至可以完全记住过去考试的答案; 另一名学生可能会通过试图理解给出某些答案的原因来做准备; 在大多数情况下, 后者会考得更好;
如果训练误差和验证误差都很严重, 但它们之间仅有一点差距; 如果模型不能降低训练误差, 这可能意味着模型过于简单(即表达能力不足), 无法捕获试图学习的模式; 此外, 由于我们的训练和验证误差之间的泛化误差很小, 我们有理由相信可以用一个更复杂的模型降低训练误差; 这种现象被称为欠拟合(underfitting); 另一方面, 当我们的训练误差明显低于验证误差时要小心, 这表明严重的过拟合(overfitting); 注意, 过拟合并不总是一件坏事; 而解决过拟合一般都是用正则化方法, 例如权重衰减和暂退法;
权重衰减
正则化的目标是减小方差或是说减小数据扰动所造成的影响; 这里引入一个概念: 噪声(Noise): 当前任务任何学习算法能达到的期望泛化误差的下界;
我们可以通过减少神经网络的神经元个数, 也就是让权重的数量少一点来使得模型不那么复杂来解决过拟合;
我们也可以通过让权重的取值范围小一点来解决, 这可以使得我们的模型波动没有那么大, 也可以有效的降低模型复杂度, 使得模型不会过拟合, 那么这个方法就是权重衰退;
以多项式回归为例, 根据训练数据的点集我们会拟合出一条多项式曲线(y1 = w1x1 + w2x22 + w3x33... + wdxdd) 该多项式表示该模型有d个特征; 过拟合意味着该曲线为了去尽量拟合所有训练数据而归于曲折, 因此不具有泛化; 当此时我们删除一个特征时曲线会明显变得平滑, 想象一下, 对于一系列点集, 当我们用三次函数拟合后会产出一个波浪号形状的曲线, 此时我们删除特征x33, 那么就会变成一个二次函数, 为了去拟合点集, 二次函数的两条边的夹角会变大, 整个图像也变得平缓; 但是直接删除一个特征未免太过, 所以我们改为调整权重, 当w3设为非常小时, x33的影响就不大了, 这样会比直接删除更灵活;
暂退法(Dropout)
造成过拟合的情况大致分为3类:
- 权重值的范围太大, 导致模型极其不稳定;
- 对于简单的数据选取的模型过于复杂, 比如隐藏层过多, 隐藏层的神经元过多;
- 训练样本过少, 导致模型对少样本完全拟合, 对于新样本极其陌生
权重衰减就是针对情况1提出的解决方案, 该方案对损失函数作了处理, 新的损失函数在原有的损失函数后面加上了一个L2正则, 这可以使得模型在做梯度下降时, 使得每次的权重值相比原来下降的更多一些, 可以有效的使得最后的权重值收缩的比较小, 解决过拟合的问题;
但这个方案现在用的不是很多, 实际上我们在碰到一个样本的时候, 一开始选取的模型肯定无法保证是最优模型的, 可能过深或者过浅, 只有在多次调试, 调整超参数才能使得模型容量变得比较合适, 导致过拟合的主要原因还是出在模型复杂度的调整上, 暂退法可以减少隐藏神经元个数同时对整个神经网络不产生影响;
暂退法的思路是提高模型的平滑性, 做法是我们在训练过程中人为地向网络中的每一层注入随机噪声; 具体的操作则是随机地丢弃一些神经元, 但是丢弃后要对剩余的神经元进行处理使得期望保持不变, 设丢弃的概率为p, 对于保留下来的神经元应该由h修改为h/(1-p), 其他的神经元设为0;
模型初始化
在这之前我们先引出两个概念: 梯度爆炸和梯度消失; 在反向传播时我们会遵循链式法则, 当求导>1时, 随着层数增大, 梯度会呈指数形式增大, 反之<1时就会呈指数形式衰减; 对应的就是梯度爆炸和梯度消失;
所以为了避免以上两种情况, 我们可以使用Xavier初始化; 首先为了避免梯度消失或爆炸, 我们要保证每一层的输出拉回到一个区间, 也就是让每个层的输出方差都相同; 这样就能够避免后面层的激活函数的输出值趋向于0;
我们把每层的输出和梯度都看作随机变量, 让他们的均值和方差都保持一致, 均值为0, 方差为一个常数