从零开始构建简单人工神经网络:1个输入层和1个输出层
上篇将介绍构建一个很简单的ANN,只有1个输入层和1个输出层,没有隐藏层。
下篇将介绍构建一个有1个输入层、1个隐藏层和1个输出层的ANN。
为何从零开始?
有许多深度学习库(Keras、TensorFlow和PyTorch等)可仅用几行代码构建一个神经网络。然而,如果你真想了解神经网络的底层运作,建议学习如何使用Python或任何其他编程语言从零开始为神经网络编程。
不妨创建某个随机数据集:
图1. 为简单起见,随机数据集带二进制值
上面表格有五列:Person、X1、X2、X3和Y。1表示true,0表示false。我们的任务是创建一个能够基于X1、X2和X3的值来预测Y值的人工神经网络。
我们将创建一个有1个输入层、1个输出层而没有隐藏层的人工神经网络。开始编程前,先不妨看看我们的神经网络在理论上将如何执行:
ANN理论
人工神经网络是一种监督式学习算法,这意味着我们为它提供含有自变量的输入数据和含有因变量的输出数据。比如在该示例中,自变量是X1、X2和X3,因变量是Y。
首先,ANN进行一些随机预测,将这些预测与正确的输出进行比较,计算出误差(预测值与实际值之间的差)。找出实际值与传播值之间的差异的函数名为成本函数(cost function)。这里的成本指误差。我们的目标是使成本函数最小化。训练神经网络基本上是指使成本函数最小化。下面会介绍如何执行此任务。
神经网络分两个阶段执行:前馈阶段和反向传播阶段。下面详细介绍这两个步骤。
前馈
图2
来源:单层神经网络,又叫Perceptron
在ANN的前馈阶段,基于输入节点中的值和权重进行预测。如果看一下上图中的神经网络,会看到数据集中有三个特征:X1、X2和X3,因此第一层(又叫输入层)中有三个节点。
神经网络的权重基本上是我们要调整的字符串,以便能够正确预测输出。请记住,每个输入特性只有一个权重。
以下是在ANN的前馈阶段所执行的步骤:
第1步:计算输入和权重之间的点积
输入层中的节点通过三个权重参数与输出层连接。在输出层中,输入节点中的值与对应的权重相乘并相加。最后,偏置项b添加到总和。
为什么需要偏置项?
假设某个人有输入值(0,0,0),输入节点和权重的乘积之和将为零。在这种情况下,无论我们怎么训练算法,输出都将始终为零。因此,为了能够做出预测,即使我们没有关于该人的任何非零信息,也需要一个偏置项。偏置项对于构建稳健的神经网络而言必不可少。
数学上,点积的总和:
X.W=x1.w1 + x2.w2 + x3.w3 + b
第2步:通过激活函数传递点积(X.W)的总和
点积XW可以生成任何一组值。然而在我们的输出中,我们有1和0形式的值。我们希望输出有同样的格式。为此,我们需要一个激活函数(Activation Function),它将输入值限制在0到1之间。因此,我们当然会使用Sigmoid激活函数。
图3. Sigmoid激活函数
输入为0时,Sigmoid函数返回0.5。如果输入是大正数,返回接近1的值。负输入的情况下,Sigmoid函数输出的值接近零。
因此,它特别适用于我们要预测概率作为输出的模型。由于概念只存在于0到1之间,Sigmoid函数是适合我们这个问题的选择。
上图中z是点积X.W的总和。
数学上,Sigmoid激活函数是:
图4. Sigmoid激活函数
总结一下到目前为止所做的工作。首先,我们要找到带权重的输入特征(自变量矩阵)的点积。接着,通过激活函数传递点积的总和。激活函数的结果基本上是输入特征的预测输出。
反向传播
一开始,进行任何训练之前,神经网络进行随机预测,这种预测当然是不正确的。
我们先让网络做出随机输出预测。然后,我们将神经网络的预测输出与实际输出进行比较。接下来,我们更新权重和偏置,并确保预测输出更接近实际输出。在这个阶段,我们训练算法。不妨看一下反向传播阶段涉及的步骤。
第1步:计算成本
此阶段的第一步是找到预测成本。可以通过找到预测输出值和实际输出值之间的差来计算预测成本。如果差很大,成本也将很大。
我们将使用均方误差即MSE成本函数。成本函数是找到给定输出预测成本的函数。
图5. 均方误差
这里,Yi是实际输出值,Ŷi是预测输出值,n是观察次数。
第2步:使成本最小化
我们的最终目的是微调神经网络的权重,并使成本最小化。如果你观察仔细,会了解到我们只能控制权重和偏置,其他一切不在控制范围之内。我们无法控制输入,无法控制点积,无法操纵Sigmoid函数。
为了使成本最小化,我们需要找到权重和偏置值,确保成本函数返回最小值。成本越小,预测就越正确。
要找到函数的最小值,我们可以使用梯度下降算法。梯度下降可以用数学表示为:
图6. 使用梯度下降更新权重