PyTorch自动驾驶视觉感知算法实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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

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

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

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

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

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

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

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

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

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

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

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

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

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

求导也很简单:

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

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

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