美文网首页科技
神经网络与深度学习基础笔记

神经网络与深度学习基础笔记

作者: 郭少悲 | 来源:发表于2017-07-21 11:51 被阅读29次

    前进的道路上,我们将扩展出很多关于神经网络的关键的思想,其中包括两个重要的人工神经元 (感知机和 S 型神经元),以及标准的神经网络学习算法,即随机梯度下降算法。自始至终,我专注于解释事情的原委,并构筑你对神经网络的直观感受。

    感知机


    感知机在20世纪五、 六十年代由科学家 Frank Rosenblatt 发明,其受到 Warren McCulloch 和 Walter Pitts 早期著 作的影响。今天,使用其它人工神经元模型更为普遍---在这本书中,以及更多现代的神经网络著作中,主要使用的是一种叫做 S 型神经元的神经元模型。我们很快会讲到S型神经元。但是要理解为什么S型神经元被定义为那样的方式,值得花点时间先来理解下感知机。

    感知机是如何工作的呢?

    一个感知机接受几个二进制输入,x1, x2, . . .,并产生一个二进制输 出:

    image.png

    示例中的感知机有三个输入,x1, x2, x3。通常可以有更多或更少输入。Rosenblatt 提议一个简单的规则来计算输出。他引入权重,w1, w2, . . .,表示相应输入对于输出重要性的实数。神经 元的输出,0 或者 1,则由分配权重后的总和 ∑ wjxj 小于或者大于一些阈值决定。和权重一样,阈值是一个实数,一个神经元的参数。用更精确的代数形式:

    image.png

    这就是感知机要做的事情,一个基本的数学模型。

    image.png

    在这个网络中,第一列感知机 —— 我们称其为第一层感知机 —— 通过权衡输入依据做出三 个非常简单的决定。那第二层的感知机呢?每一个都在权衡第一层的决策结果并做出决定。以这种方式,一个第二层中的感知机可以比第一层中的做出更复杂和抽象的决策。在第三层中的感 知机甚至能进行更复杂的决策。以这种方式,一个多层的感知机网络可以从事复杂巧妙的决策。
    顺便提一下,当我定义感知机时我说的是感知机只有一个输出。在上面的网络中感知机看上 去像是有多个输出。实际上,他们仍然是单输出的。多个感知机输出箭头仅仅便于说明一个感 知机的输出被用于其它感知机的输入。

    让我们简化感知机的数学描述。条件 ∑ wjxj 看上去有些冗⻓,我们可以创建两个符号的变动来简化。第一个变动是把∑wjxj 改写成点乘,w · x ≡ ∑wjxj,这里 w 和 x 对应权重和输入的向量。第二个变动是把阈值移到不等式的另一边,并用感知机的偏置 b ≡ −threshold 代替。用偏置而不是阈值,那么感知机的规则可以重写为:

    image.png

    S型神经元


    我们用描绘感知机的相同方式来描绘 S 型神经元:

    image.png

    正如一个感知机,S型神经元有多个输入,x1,x2,...。但是这些输入可以取 0 和 1 中的任意值,而不仅仅是 0 或 1。例如,0.638 . . . 是一个S型神经元的有效输入。同样,S型神经元对每个输入有权重,w1,w2,...,和一个总的偏置,b。但是输出不是 0 或 1。相反,它现在是 σ(w · x + b),这里 σ 被称为S 型函数,定义为:

    image.png

    把它们放在一起来更清楚地说明,一个具有输入 x1, x2, . . .,权重 w1, w2, . . .,和偏置 b 的 S 型神经元的输出是:

    image.png

    为了理解和感知机模型的相似性,假设 z ≡ w · x + b 是一个很大的正数。那么 e−z ≈ 0 而 σ(z) ≈ 1。即,当 z = w · x + b 很大并且为正,S 型神经元的输出近似为 1,正好和感知机一样。 相反地,假设 z = w·x+b 是一个很大的负数。那么 e−z → ∞,σ(z) ≈ 0。所以当 z = w·x+b 是一个很大的负数,S 型神经元的行为也非常近似一个感知机。只有在 w · x + b 取中间值时, 和感知机模型有比较大的偏离。

    σ 的精确形式不重要 —— 重要的是这个函数绘制的形状。是这样:

    image.png

    这个形状是阶跃函数平滑后的版本:

    image.png

    如果 σ 实际是个阶跃函数,既然输出会依赖于 w · x + b 是正数还是负数2,那么 S 型神经元会成为一个感知机。利用实际的 σ 函数,我们得到一个,就像上面说明的,平滑的感知机。确实,σ函数的平滑特性,正
    是关键因素,而不是其细部形式。σ 的平滑意味着权重和偏置的微小变化,即 ∆wj 和 ∆b,会从神经元产生一
    个微小的输出变化 ∆output。实际上,微积分告诉我 们 ∆output 可以很好地近似表示为:

    image.png

    它的意思非常简单:∆output 是一个反映权重和偏置变化 —— 即 ∆wj 和 ∆b —— 的线性函数。利用这个线性特性,我们比较容易细微地修改权重 和偏置的值,从而获得我们需要的细微的输出变化。所以,因为S型神经元具有与感知机类似的本质行为,它们可以帮助我们了解权重和偏置的变化如何影响输出值。

    我们应该如何解释一个 S 型神经元的输出呢? 很明显,感知机和 S 型神经元之间一个很大的不同是 S 型神经元不仅仅输出 0 或 1。它可以输出 0 到 1 之间的任何实数,所以诸如 0.173和0.689的值是合理的输出。

    神经网络的架构


    image.png

    这个网络中最左边的称为输入层,其中的神经元称为输入神经元。最右边的, 输出层包含有输出神经元,在本例中,输出层只有一个神经元。中间层,既然这层中的神经元既不是输入也不是输出,则被称为隐藏层

    相比于神经网络中输入输出层的直观设计,隐藏层的设计则堪称一⻔艺术。特别是,通过一些简单的经验法则来总结隐藏层的设计流程是不可行的。相反,神经网络的研究人员已经为隐藏层开发了许多设计最优法则,这有助于网络的行为能符合人们期望的那样。例如,这些法则可以用于帮助权衡隐藏层数量和训练网络所需的时间开销。

    目前为止,我们讨论的神经网络,都是以上一层的输出作为下一层的输入。这种网络被称为前馈神经网络。这意味着网络中是没有回路的 —— 信息总是向前传播,从不反向回馈。如果确 实有回路,我们最终会有这样的情况:σ 函数的输入依赖于输出。

    一个简单的分类手写数字的网络


    定义神经网络后,让我们回到手写识别上来。我们可以把识别手写数字的问题分成两个子问题。
    首先,我们希望有个方式把包含许多数字的图像分成一系列单独的图像,每个包含单个数字。
    其次,我们将专注于编程解决第二个问题,识别单独的数字。

    我们将使用一个三层神经网络来识别单个数字:

    image.png

    网络的输出层包含有 10 个神经元。如果第一个神经元激活,即输出 ≈ 1,那么表明网络认为数字是一个0。如果第二个神经元激活,就表明网络认为数字是一个1。依此类推。更确切地说,我们把输出神经元的输出赋予编号 0 到 9,并计算出那个神经元有最高的激活值。比如,如果编号为 6 的神经元激活,那么我们的网络会猜到输入的数字是6。其它神经元相同。

    你可能会好奇为什么我们用 10 个输出神经元。毕竟我们的任务是能让神经网络告诉我们哪个数字(0, 1, 2, . . . , 9 )能和输入图片匹配。一个看起来更自然的方式就是使用4个输出神经元,把每一个当做一个二进制值,结果取决于它的输出更靠近 0 还是 1 。四个神经元足够编码这个问题了,因为 2 ^ 4 = 16 大于 10 种可能的输入。为什么我们反而要用 10 个神经元呢? 这样做难道效率不低吗? 最终的判断是基于经验主义的: 我们可以实验两种不同的网络设计,结果证明对于这个特定的问题而言,10个输出神经元的神经网络比 4 个的识别效果更好。但是令我们好奇的是为什么使用 10 个输出神经元的神经网络更有效呢。有没有什么启发性的方法能提前告诉我们用10个输出编码比使用4个输出编码更有好呢?

    为了理解为什么我们这么做,我们需要从根本原理上理解神经网络究竟在做些什么。首先考 虑有 10 个神经元的情况。我们首先考虑第一个输出神经元,它告诉我们一个数字是不是 0。它能那么做是因为可以权衡从隐藏层来的信息。隐藏层的神经元在做什么呢?假设隐藏层的第一个神经元只是用于检测如下的图像是否存在:

    image.png

    为了达到这个目的,它通过对此图像对应部分的像素赋予较大权重,对其它部分赋予较小 的权重。同理,我们可以假设隐藏层的第二,第三,第四个神经元是为检测下列图片是否存在:

    image.png

    就像你能猜到的,这四幅图像组合在一起构成了前面显示的一行数字图像中的 0:

    image.png

    如果所有隐藏层的这四个神经元被激活那么我们就可以推断出这个数字是 0。当然,这不是 我们推断出 0 的唯一方式 —— 我们能通过很多其他合理的方式得到 0 (举个例子来说,通过上述图像的转换,或者稍微变形)。但至少在这个例子中我们可以推断出输入的数字是 0。

    假设神经网络以上述方式运行,我们可以给出一个貌似合理的理由去解释为什么用 10 个输 出而不是 4 个。如果我们有 4 个输出,那么第一个输出神经元将会尽力去判断数字的最高有效位是什么。把数字的最高有效位和数字的形状联系起来并不是一个简单的问题。很难想象出有 什么恰当的历史原因,一个数字的形状要素会和一个数字的最高有效位有什么紧密联系。

    上面我们说的只是一个启发性的方法。没有什么理由表明这个三层的神经网络必须按照我所 描述的方式运行,即隐藏层是用来探测数字的组成形状。可能一个聪明的学习算法将会找到一 些合适的权重能让我们仅仅用 4 个输出神经元就行。但是这个启发性的方法通常很有效,它会节省你大量时间去设计一个好的神经网络结构。

    使用梯度下降算法进行学习


    我们将使用 MNIST 数据集,其包含有数以万计的连 带着正确分类器的手写数字的扫描图像。MNIST 的名字来源于 NIST ——美国国家标准与技术 研究所 —— 收集的两个数据集改进后的子集。

    我们希望有一个算法,能让我们找到权重和偏置,以至于网络的输出 y(x) 能够拟合所有的训练输入 x。为了量化我们如何实现这个目标,我们定义一个代价函数:

    image.png

    这里 w 表示所有的网络中权重的集合,b 是所有的偏置,n 是训练输入数据的个数,a 是表示当输入为 x 时输出的向量,求和则是在总的训练输入 x 上进行的。当然,输出 a 取决于 x, w 和 b,但是为了保持符号的简洁性,我没有明确地指出这种依赖关系。符号 ∥v∥ 是指向量 v 的模。我们把 C 称为二次代价函数;有时也被称为均方误差或者 MSE

    观察二次代价函数的形式我们可以看到 C(w, b)是非负的,因为求和公式中的每一项都是非负的。此外,代价函数 C(w,b) 的值相当小,即 C(w,b) ≈ 0,精确地说,是当对于所有的训练输入 x,y(x) 接近于输出 a 时。因此如果我们的学习算法能找到合适的权重和偏置,使得 C(w, b) ≈ 0,它就能很好地工作。相反,当 C(w, b) 很大时就不怎么好了,那意味着对于大量地输入,y(x) 与输出 a 相差很大。 因此我们的训练算法的目的,是最小化权重和偏置的代价函数 C(w, b)。换句话说,我们想要找到一系列能让代价尽可能小的权重和偏置。我们将采用称为梯度下降的算法来达到这个目的。

    假设 C 是一个有 m 个变量 v1, ..., vm 的多元函数。那么对 C 中 自变量的变化 ∆v = (∆v1, ..., ∆vm)T ,∆C 将会变为:

    image.png

    这里的梯度 ∇C 是向量

    image.png

    我们可以选取

    image.png

    这里的 η 是个很小的正数(称为学习速率) 。

    这给了我们一种方式从梯度中去取得最小值, 即使 C 是任意的多元函数,我们也能重复运用更新规则

    image.png

    事实上,甚至有一种观点认为梯度下降法是求最小值的最优策略。假设我们正在努力去改变 ∆v 来让 C 尽可能地减小。这相当于最小化 ∆C ≈ ∇C · ∆v。我们首先限制步⻓为小的固定值, 即 ∥∆v∥ = ε,ε > 0。当步⻓固定时,我们要找到使得 C 减小最大的下降方向。可以证明,使得 ∇C ·∆v 取得最小值的 ∆v 为 ∆v = −η∇C,这里 η = ε/∥∇C∥ 是由步⻓限制 ∥∆v∥ = ε 所决定的。因此,梯度下降法可以被视为一种在 C 下降最快的方向上做微小变化的方法

    反向传播


    反向传播算法最初在 1970 年代被提及,但是人们直到 David Rumelhart、Geo rey Hinton 和 Ronald Williams 的著名的 1986 年的论文中才认识到这个算法的重要性。这篇论文描述了对一些神经网络反向传播要比传统的方法更快,这使得使用神经网络来解决之前无法完成的问题变得可行。现在,反向传播算法已经是神经网络学习的重要组成部分了。

    反向传播的核心是一个对代价函数 C 关于任何权重 w (或者偏置 b )的 偏导数 ∂C/∂w 的表达式。这个表达式告诉我们在改变权重和偏置时,代价函数变化的快慢。尽管表达式会有点复杂,不过里面也包含一种美感,就是每个元素其实是拥有一种自然的直觉上的解释。所以反向传播不仅仅是一种学习的快速算法。实际上它让我们细致领悟如何通过改变权 重和偏置来改变整个网络的行为。因此,这也是学习反向传播细节的重要价值所在。

    反向传播的四个基本方程

    image.png

    输出层误差的方程

    image.png

    使用下一层的误差来表示当前层的误差

    image.png

    代价函数关于网络中任意偏置的改变率

    image.png

    代价函数关于任何一个权重的改变率

    image.png

    两个神经元之间的连接其实是关联与一个变化率因子,这仅仅是一个神经元的激活值相对于其他神经元的激活值的偏导数。从第一个权重到第一个神经元的变化率因子是 ∂a /∂w 。路径的变化率因子其实就是这条路径上的众多因子的乘积。而整个的变化率就是对于所有可能的从初始权重到最终输出的代价函数的路径的变化率因子的和。

    反向传播就是一种巧妙地追踪权重(和偏置)微小变化的传播,抵达输出层影响代价函数的技术。

    改进神经网络的学习方法

    涉及的技术包括:更好的代价函数的选择 —— 交叉熵代价函数;四种称为“正则化”的 方法(L1 和 L2 正则化,弃权和训练数据的人为扩展),这会让我们的网络在训练集之外的数据 上更好地泛化;更好的权重初始化方法;还有帮助选择好的超参数的启发式想法。

    交叉熵代价函数

    假设,我们现在要训练一 个包含若干输入变量的的神经元,x1, x2, . . . 对应的权重为 w1, w2, . . . 和偏置 b:

    image.png

    神经元的输出就是 a = σ(z),其中 z = ∑ wj xj + b 是输入的带权和。我们如下定义这个神经元的交叉熵代价函数:

    image.png

    当我们使用二次代价函数时,学习在神经元犯了明显的错误的时候却比学习快接近 真实值的时候缓慢;而使用交叉熵学习正是在神经元犯了明显错误的时候速度更快。特别地,当 我们使用二次代价函数时,当神经元在接近正确的输出前犯了明显错误的时候,学习变得更加缓慢;而使用交叉熵,在神经元犯明显错误时学习得更快。这些现象并不依赖于如何设置学习速率。

    过度拟合与正则化


    过度拟合是神经网络的一个主要问题。这在现代网络中特别正常,因为网络权重和偏置数量巨大。为了高效地训练,我们需要一种检测过度拟合是不是发生的技术,这样我们不会过度训练。并且我们也想要找到一些技术来降低过度拟合的影响。

    一般来说,最好的降低过度拟合的方式之一就是增加训练样本的量。有了足够的训练数据,就算是一个规模非常大的网络也不大容易过度拟合。不幸的是,训练数据其实是很难或者很昂贵的资源,所以这不是一种太切实际的选择。

    幸运的是,还有其他的技术能够缓解过度拟合,即使我们只有一个固定的网络和固定的训练集合。这种技术就是正则化。本节,我会给出一种最为常用的正则化手段 —— 有时候被称为权重衰减或者 L2正则化。L2 正则化的想法是增加一个额外的项到代价函数上,这个项叫做正则化项。下面是正则化的交叉熵:

    image.png

    其中第一个项就是常规的交叉熵的表达式。第二个现在加入的就是所有权重的平方的和。然 后使用一个因子 λ/2n 进行量化调整,其中 λ > 0 可以称为规范化参数,而 n 就是训练集合的 大小。我们会在后面讨论 λ 的选择策略。需要注意的是,正则化项里面并不包含偏置。

    直觉地看,正则化的效果是让网络倾向于学习小一点的权重,其他的东西都一样的。大的权重只有能够给出代价函数第一项足够的提升时才被允许。换言之,正则化可以当做一种寻找小 的权重和最小化原始的代价函数之间的折中。这两部分之间相对的重要性就由 λ 的值来控制了: λ 越小,就偏向于最小化原始代价函数,反之,倾向于小的权重。

    正则化在实践中能够减少过度拟合了。这是令人振奋的,不过,这背后的原 因还不得而知!通常的说法是:小的权重在某种程度上,意味着更低的复杂性,也就对数据给出了一种更简单却更强大解释,因此应该优先选择。

    所以,我们应当时时记住这一点,正则化的神经网络常常能够比非正则化的泛化能力更强, 这只是一种实验事实(empirical fact)。

    激活函数的作用


    摘自:https://www.zhihu.com/question/22334626

    激活函数(Activation Function)是用来加入非线性因素的,因为线性模型的表达能力不够。

    以下,同种颜色为同类数据。
    某些数据是线性可分的,意思是,可以用一条直线将数据分开。比如下图:

    image.png

    这时候你需要通过一定的机器学习的方法,比如感知机算法(perceptron learning algorithm) 找到一个合适的线性方程。
    但是有些数据不是线性可分的。比如如下数据:

    image.png

    第二组数据你就没有办法画出一条直线来将数据区分开。
    这时候有两个办法,第一个办法,是做线性变换(linear transformation),比如讲x,y变成x2,y2,这样可以画出圆形。如图所示:

    image.png
    如果将坐标轴从x,y变为以x2,y2为标准,你会发现数据经过变换后是线性可分的了。大致示意图如下: image.png

    另外一种方法是引入非线性函数。
    我们来看异或问题(xor problem)。以下是xor真值表:

    image.png

    个真值表不是线性可分的,所以不能使用线性模型,如图所示:

    image.png

    我们可以设计一种神经网络,通过激活函数来使得这组数据线性可分。
    激活函数我们选择阀值函数(threshold function),也就是大于某个值输出1(被激活了),小于等于则输出0(没有激活)。这个函数是非线性函数。
    神经网络示意图如下:

    image.png

    其中直线上的数字为权重。圆圈中的数字为阀值。第二层,如果输入大于1.5则输出1,否则0;第三层,如果输入大于0.5,则输出1,否则0。

    我们来一步步算。第一层到第二层(阀值1.5):

    image.png

    第二层到第三层(阀值0.5):

    image.png

    可以看到第三层输出就是我们所要的xor的答案。
    经过变换后的数据是线性可分的(n维,比如本例中可以用平面),如图所示:

    image.png

    这是一个单层的感知机, 也是我们最常用的神经网络组成单元啦. 用它可以划出一条线, 把平面分割开:

    image.png

    那么很容易地我们就会想用多个感知机来进行组合, 获得更强的分类能力, 这是没问题的啦~~~~ 如图所示:

    image.png

    那么我们动笔算一算, 就可以发现, 这样一个神经网络组合起来,输出的时候无论如何都还是一个线性方程哎~~~~纳尼, 说好的非线性分类呢?

    我们在每一层叠加完了以后, 加一个激活函数, 如图中的 image.png

    有了这样的非线性激活函数以后, 神经网络的表达能力更加强大。

    image.png

    加上非线性激活函数之后, 我们就有可能学习到这样的平滑分类平面。

    image.png

    所以到这里为止,我们就解释了这个观点,加入激活函数是用来加入非线性因素的,解决线性模型所不能解决的问题。

    image.png

    相关文章

      网友评论

        本文标题:神经网络与深度学习基础笔记

        本文链接:https://www.haomeiwen.com/subject/xeoskxtx.html