购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.1 神经网络回顾

本节将简要回顾神经网络的基础知识。一般来说,神经网络的使用可以分为三个步骤: 模型构建(Model),训练(Training)和推断(Inference)。 首先,需要设计神经网络模型,然后使用数据对模型进行训练。当模型具有一定的预测能力后,可以使用该模型对新数据进行推断,获得对新数据的预测值。这些预测值在不同的任务中有不同的应用。例如,股价预测模型可用于预测未来的股价,以指导投资;天气预测模型可用于预测明天的天气;人脸识别模型可用于识别照片中的人脸位置等。

1.1.1 神经网络模型

最简单的神经网络早在20世纪60年代就发明出来了,后来发展出了现在广泛使用的多层感知机(Multi Layer Perceptron, MLP)。多层感知机的基本网络结构如图1-1所示。

输入层 X 是一个一维向量,输出层 f 则是神经网络计算出来的预测值。举个实际应用的例子。假如这个神经网络被用来预测明日的股价, X 可以是前几天的股价涨跌幅, f 就是股票明天的涨跌幅了。那么神经网络的内部发生了什么?一般而言,神经网络是由一层一层的网络层组成的,每一层都会对输入向量进行一系列的运算,从而得到输出值。因为神经网络的作用可以被认为是对输入进行特征提取,所以每一层的输出值都被称为这一层的特征(Feature)。图1-1中 f 1 便是第一层神经网络的输出特征。可以用式(1-1)来表达第一层网络进行的运算:

· 图1-1 多层感知机

式中, W 1 称作权重(Weight),是一个二维矩阵。图1-1中 X 是一个维度为3的向量,输出的特征 f 1 是一个维度为4的向量,那么 W 1 就是一个3×4的矩阵,它的作用是通过线性变换把一个3维空间的输入向量投射(Project)到一个4维的特征空间中去。 b 1 称作偏置(bias),是一个长度为4的向量。

ϕ 称作激活函数(Activation Function),之所以称其为激活函数,是因为神经网络的设计灵感来自于人类的神经元。人类神经元的树突接收来自多个神经元传递过来的信号,将它们积累起来。当电位累积到一定阈值时,神经元会激活并向下一个神经元传递信号,这被称为神经冲动。激活函数仿照人类神经元的激活方式设计,如常用的ReLU激活函数,可以用式(1-2)表达:

ReLU函数的作用很简单,如果输入不超过阈值0,就不输出(输出为0),如果超过阈值了,就把这个输入原原本本地传导到下一个神经元。通过观察图1-2中所示的ReLU激活函数的图形能够更直观地理解它的作用。

· 图1-2 ReLU激活函数

于是第一层的完整公式就很容易写出来了:

激活函数必须是非线性变换 ,ReLU是由两个线性变换组合而成的分段函数,属非线性函数。简单地说,每一层神经网络都会对输入向量进行线性变换和非线性变换之后得到输出特征。第二层神经网络接收到了第一层的输出,也会进行一番线性变换和激活,就得到了最终的输出值 f

因为输出层输出的是股票明日的涨跌幅,且输出层不需要激活函数,这样输出的数值就可以是负无穷到正无穷之间的任意数值了,也就是说 ϕ 2 可以去掉。那么直接将两层神经网络的输入、输出连接起来,就可以得到整个神经网络的公式:

式中, F X )便是整个神经网络的函数。

1.1.2 神经网络的训练——反向传播算法

神经网络一般使用反向传播算法通过对损失函数进行优化来训练。训练的逻辑是通过更新模型参数使得模型计算出来的损失值变小,让模型变得越来越准确。训练开始之前,神经网络的参数(权重和偏置)都是随机数,模型输出的预测值通常和训练数据中的真实值相差较大。通过计算预测值和真实值的差别,能知道当前模型的错误,根据这个错误去更新每一层的参数,就可以让结果变得更接近真实值,这被称为一次更新。经过多次更新,模型的输出会越来越接近真实值,这就是神经网络的训练过程。

假设训练数据集中总共有 n 个数据样本,其中第 i 个样本的输入是 X i ,对应的真实值是 y i ,模型的输出是 F X i )。模型的输出和真实值之间存在一个误差,通常使用损失函数(Loss Function)来计算这个误差(对于不同类型的真实值,损失函数也不尽相同)。本例中,真实值是明日股价的涨跌幅,是一个回归问题,可以采用均方误差(Mean Squared Error,MSE)作为损失函数:

均方误差损失函数会把每一个样本的预测值和真实值的误差的平方加起来并计算平均值。很显然,误差越小,模型就越精确,于是模型的训练可以作为一个优化问题来解决:

式(1-7)的意思是通过优化神经网络的函数 F 使损失值最小,以得到一个最优的模型 。当神经网络的结构确定了,接下来就要确定其函数 F 的参数,即每一层的权重 W 1 W 2 和偏置 b 1 b 2 。也就是说神经网络的参数是优化的目标。

假如使用梯度下降(Gradient Descent,GD)算法来优化 F F 函数的参数形成一个高维参数空间的话,那么这个参数空间的一个点就对应一个 F 函数。 因为神经网络有很多层,每一层都有自己的权重和偏置,整个参数空间的维度就变得很大。为了方便绘图,用图1-3中横轴对应 F 函数的参数空间,纵轴对应损失函数的值,这样就形成了一条损失曲线。图1-3所示为一个神经网络的训练过程,随机初始化之后, F 函数位于初始位置,这个时候损失值很大。然后用梯度下降法来更新 F 函数的参数,使之按照梯度下降的方向向左移动,直到达到局部极小损失值。之所以说是局部极小,是因为神经网络的损失曲线是高度非线性的非凸函数,在参数空间的另一个位置,很可能还存在一个全局极小值,因为梯度下降法的限制,只能求得局部极小值。幸运的是,因为神经网络的一些特性,局部极小值就足够了。

· 图1-3 梯度下降算法的优化过程

假设损失函数为 L ,梯度下降过程中的某一个参数点是 F k ,经过一步迭代之后得到参数点 F k +1 ,更新过程以式(1-8)表示:

F 由很多层组成,其中每一层的参数包括权重和偏置,以图1-1所示神经网络为例,权重 W 2 的更新过程可以用式(1-9)来表示:

式(1-9)中的 λ 是学习率,决定了优化的速度。

损失函数 L 是个特别复杂的函数,直接求损失函数对模型参数的偏导未免太过繁琐,不如将损失函数 L 视为一个复合函数,然后对复合函数使用链式法则求对 W 2 的偏导,求导过程以式(1-10)表示:

式中, f 是神经网络的直接输出。如果用 f i 表示第 i 个样本的输出,那么损失函数 L 可以表示为:

对式(1-11)的求导就变得非常简单了:

再看式(1-10)的右半部分,式中的 f 可以表示为 W 2 的函数:

求导也很简单:

将式(1-12)和式(1-14)结合起来,就得到了最终的导数:

注意式(1-15)中 f 1 是第一层神经网络的输出特征,是一个4×1的向量,而等号右边的加和运算得到的是一个标量,可以看成是一个1×1的向量,两者相乘,就得到了一个4×1的梯度矩阵,和 W 2 矩阵的维度一致。读者可以自行推导第一层的权重 W 1 的梯度,可得式(1-16):

仔细观察可以发现,梯度是从损失函数开始,反向朝前一层传导的。例如,式(1-15)计算的 W 2 的梯度,只与损失函数的梯度式(1-12)以及第二层的梯度式(1-14)有关。在式(1-16)中计算 W 1 的梯度时,会使用式(1-15)中的计算结果,换句话说, W 2 的梯度传导到了 W 1 这种通过复合函数对模型参数求导的算法,就称作反向传播算法(Back Propagation,BP)。 损失函数产生的梯度通过反向传播算法传遍神经网络的每一层,然后就可以使用梯度下降算法对参数进行更新了。每一次参数更新都会让损失变得更小,模型的精度也变得高更。神经网络经过多次参数更新后,模型的精确度逐渐趋于稳定,训练便告完成。训练好的模型具备了一定的预测能力,只需将新的数据输入模型进行推断(Inference),就能获得预测值。例如,可以让模型预测明日的股价,然后参考预测值进行投资。

1.1.3 神经网络的拟合能力和泛化能力

理论上来说,如果参数量足够大,一个两层的神经网络就具有拟合任何函数的能力,这便是所谓的万能近似定理(Universal Approximation Theorem)。若是输入和输出的函数特别复杂,模型无法拟合,可以通过增加第一层的神经元数目来提高模型的拟合能力。

如此简单的结构竟能拟合任意复杂的函数,读者们一定非常疑惑。其实道理并不复杂,只要第一层的神经元数目足够多,产生的特征 f 1 维度足够大,中间层 f 1 也可以通过直接记录输入、输出对应关系的方式进行拟合。但这种理论上的拟合能力只对训练数据集有效,对于不属于训练数据集的数据不一定有效。模型对新数据的拟合能力被称为模型的泛化(Generalization)能力。

为了评测模型在新数据上的精度表现,往往会额外建立一个验证数据集(Validation Set),它包含了训练集中没有的数据,专门用来评测模型的泛化能力。一般而言,80%的数据用来建立训练集,20%的数据用来建立验证集。工程师常常使用验证集来调整模型的超参数(Hyper-Parameters),所谓 超参数是指模型的层数、每一层神经元的数目等需要自行定义的参数,这些参数无法通过训练获得。 训练集用于优化模型的可训练参数,验证集用于优化模型的超参数。为了更严格地评测模型的泛化能力,有时还会提取约10%的数据建立测试集(Testing Set),测试集可以用于最终评估模型的性能。因为在训练和调整模型超参数时,验证集的反馈可能会对模型的泛化性能产生影响,因此,测试集是一个相对独立的数据集,用于验证模型的泛化性能,并确保模型能够良好地适应未知数据。

在机器学习中,模型对训练数据拟合良好却对验证数据拟合不佳的现象称为过拟合(Overfitting),顾名思义,过拟合是指模型对训练数据进行了过度的拟合,这种情况很可能是因为模型过于复杂。如图1-4所示,深色数据点是训练数据,浅色数据点是验证数据,深色曲线表示的模型完美地拟合了每一个训练数据点,却和验证样本相差甚远。浅色直线表示的模型虽然对训练数据拟合不完美,却能更好地拟合验证样本,泛化性也更强。

· 图1-4 过拟合

除了过拟合,还有欠拟合(Underfitting),需要拟合的函数很复杂,但模型太简单就会导致欠拟合。对于神经网络而言,欠拟合比较好解决,一旦观察到训练误差太大,可以通过增加层数或增加神经元数量来提升模型的拟合能力。前文也提到了,如果神经元数量增加到一定程度,甚至可以直接把训练数据集记录下来,达到完美的拟合效果。

但训练一个神经网络,目的并不是记录训练集,而是希望模型能从训练集中学习提取有价值的特征,从而具备对新数据的认知能力,也就是所谓的泛化能力。打个比方,如果读者想要训练一个神经网络来识别偶数,最终的目的是让神经网络学习到“能够被2整除的数字是偶数”这个特征,而不是让它把训练集里的偶数记下来。如果神经网络只是把训练集里的偶数记了下来,一旦出现了一个新的偶数,模型就失效了。简而言之, 如果模型没有从训练集中学习到有意义的特征,只是简单地把训练集记下来,就是过拟合; 对于参数量太少的模型,既没能学习到有意义的特征,也没能把训练集记下来,就是欠拟合。

在训练的过程中,每一次更新完成后都会记录模型的损失值,以监测模型的训练情况。模型在训练集上的损失值会越来越小,最后稳定在低位。模型在验证集上的表现就没有这么乐观了。一开始模型在验证集上的损失会变小,但经过了一个临界点之后,模型在验证集上的损失会变得越来越大,这就说明模型过拟合了。最终会保存那个在验证集上损失最小的模型。

在经过了过拟合临界点之后,我们已经得到了泛化性能最好的模型,那是不是就可以停止训练了?工程师们一度就是这么做的,这个技术称为提前停止(Early Stopping)。如图1-5中所示的虚线,经过了第一个过拟合点之后,模型在验证集上的损失越来越大,继续训练已经没有意义了,因此可以停止训练。然而一篇由OpenAI的研究人员发表于2019年的论文指出,神经网络会出现所谓“二次下降”(Double Descent)现象 [1] ,也就是说,模型在验证集上的损失值短时间内似乎越来越大了,但随后又会变小,甚至比之前的最小值还要小。如图1-5中所示的深色实线表现的就是这个现象。考虑到这个特性,为了不要错失最优模型,一般会让训练持续到最后,然后选择整个训练过程中的最佳模型,而不是提前停止。

· 图1-5 深度神经网络的二次下降现象 cWyRykAGixeWgsNOhr0hZm88g/wJ0cunGrt4NyxkuopBgM/qkqFhauw9uuAMPmxO

点击中间区域
呼出菜单
上一章
目录
下一章
×