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

1.3 实现前向传播

为了对前向传播的工作原理有一个深入的了解,我们训练一个简单的神经网络,其中神经网络的输入是(1,1),对应的(期望)输出是0。这里将基于这个单一的输入-输出对找到神经网络的最优权重。然而,你应该注意到,事实上将有成千上万的数据点用于训练ANN。

本例中的神经网络架构包含一个具有三个节点的隐藏层,如图1-8所示。

图1-8

图1-8中每个箭头都包含一个可调的浮点值(权重)。我们需要找到9个浮点数(第一个隐藏层有6个,第二个隐藏层有3个),因此当输入是(1,1)时,输出尽可能接近(0)。这就是所谓的神经网络训练。为了简单起见,这里没有引入偏置项,但是基本的运算逻辑是一样的。

下面我们将学习下列内容:

❍ 计算隐藏层的值;

❍ 进行非线性激活;

❍ 估算输出层的值;

❍ 计算与期望值对应的损失值。

1.3.1 计算隐藏层的值

现在为所有的连接分配权重。第一步,为所有连接分配随机值作为权重。一般来说,神经网络在训练开始前使用随机权重进行初始化。同样,为了简单起见,在介绍这个主题时,前向传播和反向传播均不包括偏置项,但是我们将在从头实现前向传播和反向传播时使用它。

现在从0和1之间的随机初始化权重开始,但请注意,神经网络训练过程后的最终权重不需要限定在一组特定的值之间。图1-9a给出了网络中权重的形式化表示,图1-9b给出了网络中随机初始化的权重。

图1-9

在下一步中,我们将输入与权重相乘,计算出隐藏层中隐藏单元的值。

隐藏层激活前的单元值如下:

h 11 = x 1 × w 11 + x 2 × w 21 =1×0.8+1×0.2=1

h 12 = x 1 × w 12 + x 2 × w 22 =1×0.4+1×0.9=1.3

h 13 = x 1 × w 13 + x 2 × w 23 =1×0.3+1×0.5=0.8

计算出的隐藏层单元值(激活前)也如图1-10所示。

图1-10

现在,我们将通过非线性激活传递隐藏层的值。注意,如果不在隐藏层中应用非线性激活函数,那么无论存在多少隐藏层,神经网络从输入到输出都将成为一个巨大的线性连接。

1.3.2 应用激活函数

激活函数有助于建模输入和输出之间的复杂关系。

一些常用的激活函数计算公式如下(其中 x 为输入):

上述激活函数的可视化表示如图1-11所示。

图1-11

对于示例,我们使用Sigmoid(逻辑)函数作为激活函数。

对三个隐藏层应用Sigmoid(逻辑)激活函数 S x ),得到激活后的值如下:

现在我们获得了激活后的隐藏层的值,下一小节将获得输出层的值。

1.3.3 计算输出层的值

到目前为止,我们已经算出了应用Sigmoid(S型)激活后的最终隐藏层值。使用激活后的隐藏层值,以及权重值(在第一次迭代中随机初始化),现在将计算出网络的输出值,如图1-12所示。

图1-12

我们使用隐藏层值和权重值的乘积和来计算输出值。另外注意,这里排除了需要在每个单元(节点)上添加的偏置项,只是为了简化目前对前向传播和反向传播工作细节的理解,但将其包含在前向传播和反向传播的编码中:

因为我们从一个随机权重集合开始,所以输出节点的值与目标节点的值非常不同。在本例中,差为1.235(记住,目标为0)。在下一节中,我们将学习如何计算与当前网络状态相关的损失值。

1.3.4 计算损失值

损失值(或者称为损失函数)是需要在神经网络中进行优化的值。为了正确理解损失值是如何计算的,我们看看如下两种情况:

❍ 分类变量预测;

❍ 连续变量预测。

计算连续变量预测的损失

当变量连续时,损失值通常是实际值和预测值之差平方的平均值,也就是说,我们通过改变与神经网络相关的权重值来尽量减小均方误差。均方误差值的计算公式如下:

在上式中, y i 为实际输出; 是神经网络计算出来的预测值(其权重以 θ 的形式存储),其中输入为 x i m 为数据集的行数。

关键的结论应该是,对于每个唯一的权重集,神经网络将会预测出相应的损失值,我们需要找到损失值为零(或者,在现实场景中,尽可能接近零)的黄金权重集。

在我们的例子中,假设得到的预测结果是连续值。此时,损失函数值为均方误差,计算方法如下:

loss(误差)=1.235 2 =1.52

在理解了如何计算连续变量的损失值后,在下一小节中,我们将学习如何计算分类变量的损失值。

计算分类变量预测的损失

对于预测变量是离散值(即变量中只有几个类别)的情形,通常使用分类交叉熵损失函数。当预测变量只有两个不同取值的时候,损失函数是二元交叉熵。

二元交叉熵的计算公式如下:

y i 为实际的输出值, p i 为预测的输出值, m 为数据点总数。

一般的分类交叉熵计算公式如下:

y i 为输出的实际值, p i 为输出的预测值, m 为数据点总数, C 为类别总数。

对交叉熵损失进行可视化的一种简单方法是观察预测矩阵本身。假设需要预测图像识别问题中的五个类别——狗、猫、鼠、牛和母鸡。神经网络必须在softmax激活的最后一层包含5个神经元(下一节将详细介绍softmax)。因此,模型将预测每个数据点属于每个类别的概率。假设有5个图像,那么得到的预测概率如下表所示(每行突出显示的单元格对应于目标类):

注意,每一行的和为1。在第一行中,当目标为 、预测概率为 0.88 时,相应的损失为 0.128 (即对数 0.88 的相反数)。其他损失的计算方法与此相同。如你所见,当正确类别的概率较高时,损失值较小。如你所知,概率的范围在0和1之间。因此,可能的最小损失可以是0(当概率为1时),最大损失可以是无穷(当概率为0时)。

数据集的最终损失是所有行中所有单个损失的平均值。

现在我们已经对均方误差损失和交叉熵损失的计算有了比较透彻的理解,让我们回到这个小例子。假设输出是一个连续变量,我们将在后面的小节中学习如何使用反向传播来最小化损失值。我们将更新权重值 θ (之前随机初始化的值)来最小化损失( J θ )。但在此之前,首先需要使用NumPy数组编写前向传播Python代码,以巩固对其工作细节的理解。

1.3.5 前向传播的代码

前向传播的高级编码策略如下:

1.在每个神经元上执行乘积和。

2.计算激活。

3.在每一个神经元上重复前两步,直到输出层。

4.通过比较预测与实际输出来计算损失。

可将它看成一个函数,将输入数据、当前神经网络权重和输出数据作为函数的输入,并返回当前网络状态的损失。

下面将给出计算所有数据点的均方误差损失值的前馈函数。

下列代码可以从本书GitHub存储库(https://tinyurl.com/mcvppackt)Chapter01文件夹中的Feed_forward_propagation.ipynb获得。

强烈建议你通过单击每个notebook中的 Open in Colab 按钮来执行code notebook。截图示例如图1-13所示。

图1-13

单击 Open in Colab 按钮(图1-13中画圈部分)时,你将能够顺利地执行所有的代码,并应该能够复现本书中显示的结果。

现在有了执行代码的正确方法,下面继续编写前向传播的代码:

1.将输入变量值(inputs)、weights(如果是第一次迭代则随机初始化)和所提供数据集的实际outputs作为feed_forward的参数:

为了使这个练习更现实一些,我们将对每个节点设置偏置项。因此,权重数组不仅包含连接不同节点的权重,而且还包含隐藏/输出层中与节点相关的偏置项。

2.通过对inputs与连接输入层和隐藏层的权重值(weights[0])进行矩阵乘法(np.dot)计算隐藏层值,并将它与隐藏层节点相关的偏置项(weights[1])相加:

3.对上一步pre_hidden中获得的隐藏层值使用S型激活函数:

4.通过执行隐藏层激活值(hidden)与连接隐藏层和输出层的权重(weights[2])的矩阵乘法(np.dot)计算输出层的值,并将输出层中与节点相关的偏置项求和——weights[3]:

5.计算整个数据集的均方误差值并返回均方误差:

此时当数据向前通过网络时,就可以得到均方误差值。

在学习反向传播之前,首先需要学习之前构建的前馈网络的一些计算组件,即对激活函数和损失值的计算,可以使用NumPy进行计算,以便详细了解它们是如何工作的。

激活函数的代码

将S型激活函数应用于前面代码中隐藏层值的顶部时,我们来看看其他常用的激活函数:

Tanh ——某个值(隐藏层单元值)的tanh激活函数计算代码如下:

❍ ReLU——某个值(隐藏层单元值)的 整流线性单元 (ReLU)计算代码如下:

线性 ——某个值的线性激活就是这个值本身,计算代码如下:

softmax :与其他激活函数不同,softmax在一组值上执行。这样做通常是为了确定某个输入属于给定场景中 m 个可能输出类别中某个类别的概率。假设需要分类的图像具有10个可能的类别(对应数字0到9)。此时就有10个输出值,每个输出值代表输入图像属于这10个类别中某一个类别的概率。

softmax激活用于为输出中的每个类提供一个概率值,计算代码如下:

注意输入x上面的两个操作——np.exp将使所有值为正,除以所有这些指数的np.sum(np.exp(x))可以将所有值限制在0和1之间。这个范围与事件发生的概率一致。这就是我们所说的返回一个概率向量。

现在我们已经学习了各种激活函数,下面将学习不同的损失函数。

损失函数的代码

损失值(在神经网络训练过程中被最小化)通过更新权重值被最小化。确定合理的损失函数是建立可靠神经网络模型的关键。构建神经网络时,通常使用的损失函数如下:

均方误差 :均方误差是输出的实际值和预测值之差平方的平均值。取误差的平方,是因为误差可以是正的,也可以是负的(当预测值大于实际值时,反之亦然)。平方可以确保正误差和负误差不互相抵消。计算误差平方的平均值可以使误差在两个样本量不同的数据集之间具有可比性。

预测的输出值数组(p)与实际的输出值数组(y)之间的均方误差计算代码如下:

预测连续值的时候,通常使用均方误差。

平均绝对误差 :平均绝对误差的工作方式非常类似于均方误差。平均绝对误差通过取所有数据点上实际值和预测值之间的差值绝对值的平均数来确保正误差和负误差不相互抵消。

预测的输出值数组(p)与实际的输出值数组(y)之间的平均绝对误差计算代码如下:

与均方误差类似,连续变量通常采用平均绝对误差。此外,一般来说,在预测输出中包含小于1的值的时候,最好使用平均绝对误差作为损失函数。在预期输出小于1的时候,均方误差将大大降低损失量(-1和1之间的数字的平方是一个更小的数字)。

二元交叉熵 :交叉熵用于度量实际概率分布和预测概率分布这两种不同分布之间的差异。二元交叉熵用于处理二元输出数据,不像我们前面讨论的两个损失函数(用于对连续变量的预测)。

预测值数组(p)和实际值数组(y)之间的二元交叉熵计算代码如下:

需要注意的是,当预测值与实际值相差较大时,二元交叉熵损失较大;当预测值与实际值相近时,二元交叉熵损失较小。

分类交叉熵 :预测值数组(p)和实际值数组(y)之间的分类交叉熵实现代码如下:

目前已经学习了前向传播,以及构成前向传播的各种组件,如权重初始化、与节点相关的偏置项、激活和损失函数。在下一节中,我们将学习反向传播(backpropagation),这是一种调整权重的技术,使损失值尽可能小。 Cg1H034O3POGnqKhB05PqNi7Ax42RRwBhzB2EYSWW8YniiNcyS8DfaGawE6UwUF3

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