多层感知机
在先前的学习中,我们使用的都是单层的神经网络,很多情况下,单层神经网络的表达能力有限,而且只能解决线性问题。在这里,我们引入多层感知机便可以解决该问题。
一、隐藏层
多层感知机就是在单层线性模型的基础上加若干个隐藏层

增加了隐藏层之后,模型的记忆能力增强了一些,然而还是没有解决“只能解决线性问题”的毛病:线性变换的线性变换还是线性变换
二、激活函数
通过在隐藏层上添加激活函数,可以给模型添加非线性性质。有几类常用的激活函数。
1、ReLU
2、Sigmoid
3、tanh
事实上,还有更多种的激活函数,有的是为了解决sigmid和tanh的梯度消失问题,有的是为了解决死亡ReLU问题
三、多层感知机的Pytorch实现
多层感知机的pytorch实现只是简单地在线性回归的基础上增加了展平层、隐藏层、激活函数层,其余部分没有变化,较为简单,此处不多赘述
四、模型选择,过拟合与欠拟合
我们训练一个模型,我们总是希望它能够从训练集中去学习到一些东西,并能够正确地将其使用到现实生活中去。模型的这种能力被称为泛化能力。
泛化能力是一个抽象的概念,我们永远不能准确地计算它,我们只能用测试集去评估它
泛化能力并不是总能轻松取得:
有时候模型在训练集中表现极好,但是在测试集中表现不佳,这称为过拟合。
有时候模型在训练集上表现不佳,在测试集中也有所欠缺,这称为欠拟合。
过拟合与欠拟合有时候是由于训练数量决定的,有时候是由模型本身的复杂程度决定的。
模型越复杂(参数越多,参数取值范围越大),训练样本数量越小,越容易过拟合。
五、K折交叉验证
有时候我们的数据集并不大,我们不希望从中还得分出一部分作为测试集。为了充分利用样本数据来评估模型,我们使用K折交叉验证,也就是把数据集分成K份,其中K-1份作为训练集,最后一份作为测试集。最后在训练结果上取平均,来判断我们的模型能力。
六、正则化
在一个已有的模型上,为了避免其发生过拟合,我们并不需要推翻整个模型重构,我们只需要在损失函数上进行一些操作:添加正则化。也就是将损失函数设置为:

右侧的范数可以是一范数也可以是二范数,对于二范数而言,其对偏大的权重产生相当大的惩罚。
调整损失函数后,我们也要相应地调整更新权重的公式:

L2正则化对较大的权重施以更大的惩罚,使得权重更加平均,而L1正则化则是给所有权重施以同等程度的惩罚,因此当其惩罚较大的权重时,较小的权重很有可能变为0,所以L1正则化让权重更加稀疏,即大部分权重为0,起到特征筛选的作用。
需要在PyTorch中引用时只需要在trainer的参数中设置即可。
七、暂退法
大部分情况下,我们希望把权重分散到更多的特征中,而不是仅仅依赖其中的某一两条线路,以提高模型的泛化能力。
其中一条便是暂退法。
一种暂退法是在计算中间层结果的同时向其中注入噪声。
另一种暂退法被称为标准暂退法,也就是当对神经元进行计算时,以p的概率丢弃该神经元,不进行计算。
使用这种方法给神经网络一定的扰动,使得其能够提高泛化能力。
注意:在暂退法中,我们需要保证每个神经元的输出期望不变,也就是要讲没有丢弃的神经元的输出除以
需要在PyTorch中引用时只需要在net中添加nn.dropout()层即可。
八、梯度消失、梯度爆炸以及打破对称性
在神经网络的实际训练过程中,经常出现梯度消失问题或是梯度爆炸问题。
梯度消失:一般是激活函数导致的问题,例如sigmoid函数,当变量较大或较小时,其梯度也较小,造成梯度消失,从而导致每次参数几乎不变化。
梯度爆炸:当神经网络过深时,大量的矩阵乘法可能导致数值溢出
对称性问题:在神经网络的初始化过程中,我们如果将权重全部设为同样的值,则会导致所有神经元输出相同的结果,那么神经网络永远具有对称性,有n个神经元的效果与只有1个神经元的效果类似,如此则浪费了神经网络的表达能力。
通过适当的初始化,能够同时解决(减轻)上述问题:
Pytorch中有默认初始化的过程,其可以解决中等难度的问题。
还有另一种初始化方法:Xavier初始化
该初始化的本质思想是尽量地保持每一轮输出后输出结果的均值和方差不变,具体不过多论述。