浅谈感知机与神经网络(无师自通)

感知机与神经网络

最近十年以来,神经网络一直处于机器学习研究和应用的前沿。深度神经网络(DNN)、迁移学习以及计算高效的图形处理器(GPU)的普及使得图像识别、语音识别甚至文本生成领域取得了重大进展。

神经网络受人类大脑的启发,也被称为连接模型。像人脑一样,神经网络是大量被称为权重的突触相互连接的人造神经元的集合。

就像我们通过年长者提供的例子来学习一样,人造神经网络通过向它们提供的例子来学习,这些例子被称为训练数据集。有了足够数量的训练数据集,人造神经网络可以提取信息,并用于它们没有见过的数据。

神经网络并不是最近才出现的。第一个神经网络模型 McCulloch Pitts(MCP)早在 1943 年就被提出来了,该模型可以执行类似与、或、非的逻辑操作。

MCP 模型的权重和偏置是固定的,因此不具备学习的可能。这个问题在若干年后的 1958 年由 Frank Rosenblatt 解决。他提出了第一个具有学习能力的神经网络,称之为感知机(perceptron)。

从那时起,人们就知道添加多层神经元并建立一个深的、稠密的网络将有助于神经网络解决复杂的任务。就像母亲为孩子的成就感到自豪一样,科学家和工程师对使用神经网络(https://www.youtube.com/watch?v=jPHUlQiwD9Y)所能实现的功能做出了高度的评价。

这些评价并不是虚假的,但是由于硬件计算的限制和网络结构的复杂,当时根本无法实现。这导致了在 20 世纪 70 年代和 80 年代出现了被称为 AI 寒冬的时期。在这段时期,由于人工智能项目得不到资助,导致这一领域的进展放缓。

随着 DNN 和 GPU 的出现,情况发生了变化。今天,可以利用一些技术通过微调参数来获得表现更好的网络,比如 dropout 和迁移学习等技术,这缩短了训练时间。最后,硬件公司提出了使用专门的硬件芯片快速地执行基于神经网络的计算。

人造神经元是所有神经网络的核心。它由两个主要部分构成:一个加法器,将所有输入加权求和到神经元上;一个处理单元,根据预定义函数产生一个输出,这个函数被称为**函数。每个神经元都有自己的一组权重和阈值(偏置),它通过不同的学习算法学习这些权重和阈值:

浅谈感知机与神经网络(无师自通)
当只有一层这样的神经元存在时,它被称为感知机。输入层被称为第零层,因为它只是缓冲输入。存在的唯一一层神经元形成输出层。输出层的每个神经元都有自己的权重和阈值。

当存在许多这样的层时,网络被称为多层感知机(MLP)。MLP有一个或多个隐藏层。这些隐藏层具有不同数量的隐藏神经元。每个隐藏层的神经元具有相同的**函数:

浅谈感知机与神经网络(无师自通)
上图的 MLP 具有一个有 4 个输入的输入层,5 个分别有 4、5、6、4 和 3 个神经元的隐藏层,以及一个有 3 个神经元的输出层。在该 MLP 中,下层的所有神经元都连接到其相邻的上层的所有神经元。因此,MLP 也被称为全连接层。MLP 中的信息流通常是从输入到输出,目前没有反馈或跳转,因此这些网络也被称为前馈网络。

感知机使用梯度下降算法进行训练。前面章节已经介绍了梯度下降,在这里再深入一点。感知机通过监督学习算法进行学习,也就是给网络提供训练数据集的理想输出。在输出端,定义了一个误差函数或目标函数 J(W),这样当网络完全学习了所有的训练数据后,目标函数将是最小的。

输出层和隐藏层的权重被更新,使得目标函数的梯度减小:

浅谈感知机与神经网络(无师自通)
为了更好地理解它,想象一个充满山丘、高原和凹坑的地形。目标是走到地面(目标函数的全局最小值)。如果你站在最上面,必须往下走,那么很明显你将会选择下山,即向负坡度(或负梯度)方向移动。相同的道理,感知机的权重与目标函数梯度的负值成比例地变化。

梯度的值越大,权值的变化越大,反之亦然。现在,这一切都很好,但是当到达高原时,可能会遇到问题,因为梯度是零,所以权重没有变化。当进入一个小坑(局部最小值)时,也会遇到问题,因为尝试移动到任何一边,梯度都会增加,迫使网络停留在坑中。

正如前面所述,针对增加网络的收敛性提出了梯度下降的各种变种使得网络避免陷入局部最小值或高原的问题,比如添加动量、可变学习率。

TensorFlow 会在不同的优化器的帮助下自动计算这些梯度。然而,需要注意的重要一点是,由于 TensorFlow 将计算梯度,这也将涉及**函数的导数,所以你选择的**函数必须是可微分的,并且在整个训练场景中具有非零梯度。

感知机中的梯度下降与梯度下降的一个主要不同是,输出层的目标函数已经被定义好了,但它也用于隐藏层神经元的权值更新。这是使用反向传播(BPN)算法完成的,输出中的误差向后传播到隐藏层并用于确定权重变化。

TensorFlow常用**函数及其特点和用法(6种)详解

每个神经元都必须有**函数。它们为神经元提供了模拟复杂非线性数据集所必需的非线性特性。该函数取所有输入的加权和,进而生成一个输出信号。你可以把它看作输入和输出之间的转换。使用适当的**函数,可以将输出值限定在一个定义的范围内。

如果 xi 是第 j 个输入,Wj 是连接第 j 个输入到神经元的权重,b 是神经元的偏置,神经元的输出(在生物学术语中,神经元的**)由**函数决定,并且在数学上表示如下:

浅谈感知机与神经网络(无师自通)

这里,g 表示**函数。**函数的参数 ΣWjxj​+b 被称为神经元的活动。

这里对给定输入刺激的反应是由神经元的**函数决定的。有时回答是二元的(是或不是)。例如,当有人开玩笑的时候…要么不笑。在其他时候,反应似乎是线性的,例如,由于疼痛而哭泣。有时,答复似乎是在一个范围内。

模仿类似的行为,人造神经元使用许多不同的**函数。在这里,你将学习如何定义和使用 TensorFlow 中的一些常用**函数。

**函数

下面认识几种常见的**函数

阈值**函数:这是最简单的**函数。在这里,如果神经元的**值大于零,那么神经元就会被**;否则,它还是处于抑制状态。下面绘制阈值**函数的图,随着神经元的**值的改变在 TensorFlow 中实现阈值**函数:

浅谈感知机与神经网络(无师自通)
上述代码的输出结果:

浅谈感知机与神经网络(无师自通)
2、Sigmoid **函数:在这种情况下,神经元的输出由函数 g(x)=1/(1+exp(-x)) 确定。在 TensorFlow 中,方法是 tf.sigmoid,它提供了 Sigmoid **函数。这个函数的范围在 0 到 1 之间:

浅谈感知机与神经网络(无师自通)
在形状上,它看起来像字母 S,因此名字叫 Sigmoid

浅谈感知机与神经网络(无师自通)
3、双曲正切**函数:在数学上,它表示为 (1-exp(-2x)/(1+exp(-2x)))。在形状上,它类似于 Sigmoid 函数,但是它的中心位置是 0,其范围是从 -1 到 1。TensorFlow 有一个内置函数 tf.tanh,用来实现双曲正切**函数

以下是代码的输出结果:

浅谈感知机与神经网络(无师自通)
4、线性**函数:在这种情况下,神经元的输出与神经元的输入值相同。这个函数的任何一边都不受限制:

浅谈感知机与神经网络(无师自通)
5、整流线性单元(ReLU)**函数也被内置在 TensorFlow 库中。这个**函数类似于线性**函数,但有一个大的改变:对于负的输入值,神经元不会**(输出为零),对于正的输入值,神经元的输出与输入值相同:

一下是Rule函数的输出:

浅谈感知机与神经网络(无师自通)
6、Softmax **函数是一个归一化的指数函数。一个神经元的输出不仅取决于其自身的输入值,还取决于该层中存在的所有其他神经元的输入的总和。这样做的一个优点是使得神经元的输出小,因此梯度不会过大。数学表达式为 yi =exp(xi​)/Σjexp(xj):

浅谈感知机与神经网络(无师自通)
一下是Rule函数的输出:

浅谈感知机与神经网络(无师自通)

函数进行解释

阈值**函数用于 McCulloch Pitts 神经元和原始的感知机。这是不可微的,在 x=0 时是不连续的。因此,使用这个**函数来进行基于梯度下降或其变体的训练是不可能的。

Sigmoid **函数一度很受欢迎,从曲线来看,它像一个连续版的阈值**函数。它受到梯度消失问题的困扰,即函数的梯度在两个边缘附近变为零。这使得训练和优化变得困难。

双曲正切**函数在形状上也是 S 形并具有非线性特性。该函数以 0 为中心,与 Sigmoid 函数相比具有更陡峭的导数。与 Sigmoid 函数一样,它也受到梯度消失问题的影响。

线性**函数是线性的。该函数是双边都趋于无穷的 [-inf,inf]。它的线性是主要问题。线性函数之和是线性函数,线性函数的线性函数也是线性函数。因此,使用这个函数,不能表示复杂数据集中存在的非线性。

ReLU **函数是线性**功能的整流版本,这种整流功能允许其用于多层时捕获非线性。

使用 ReLU 的主要优点之一是导致稀疏**。在任何时刻,所有神经元的负的输入值都不会**神经元。就计算量来说,这使得网络在计算方面更轻便。

ReLU 神经元存在死亡 ReLU 的问题,也就是说,那些没有**的神经元的梯度为零,因此将无法进行任何训练,并停留在死亡状态。尽管存在这个问题,但 ReLU 仍是隐藏层最常用的**函数之一。

Softmax **函数被广泛用作输出层的**函数,该函数的范围是 [0,1]。在多类分类问题中,它被用来表示一个类的概率。所有单位输出和总是 1。

总结

神经网络已被用于各种任务。这些任务可以大致分为两类:函数逼近(回归)和分类。根据手头的任务,一个**函数可能比另一个更好。一般来说,隐藏层最好使用 ReLU 神经元。对于分类任务,Softmax 通常是更好的选择;对于回归问题,最好使用 Sigmoid 函数或双曲正切函数。