神经网络:前馈和反向传播解释和优化
作者:互联网
神经网络:前馈和反向传播解释和优化
什么是神经网络?开发人员应该了解反向传播,以找出他们的代码有时不起作用的原因。反向传播数学的视觉和脚踏实地的解释。
真正理解神经网络——深度学习(机器学习的子领域)中最受认可的概念之一是神经网络*。*
相当重要的一点是,所有类型的神经网络都是相同基本原理的不同组合。当您了解神经网络如何工作的基础知识时,新架构只是对您已经了解的有关神经网络的所有知识的小补充。
展望未来,以上内容将成为本网站上所有其他深度学习帖子的主要动机。
目录(点击滚动)
概述
神经网络的大局是我们如何从拥有一些数据,将其投入到某种算法中,并希望得到最好的结果。但是该算法内部发生了什么?出于多种原因,这个问题很重要;一个是你可能只是将神经网络的内部工作视为一个黑匣子。
神经网络由神经元组成,这些神经元之间的连接称为权重,以及连接到每个神经元的一些偏差。我们区分输入层、隐藏层和输出层,希望每一层都能帮助我们解决问题。
为了通过网络向前移动,称为前向传递,我们迭代地使用一个公式来计算下一层中的每个神经元。完全忽略这里的符号,但我们将激活神经元称为 a a a、权重 w w w 和偏差 b b b——它们在向量中累积。
a ( l ) = σ ( W a l − 1 + b ) a^{(l)}= \sigma\left( \boldsymbol{W}\boldsymbol{a}^{l-1}+\boldsymbol{b} \right) a(l)=σ(Wal−1+b)
这使我们前进,直到我们得到输出。我们通过成本函数 C C C 和我们在输出层 y y y 中想要的结果来衡量这个输出 y ^ \hat{y} y^ 的好坏,我们对每个示例都这样做。这通常称为均方误差 (MSE):
C = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 C = \frac{1}{n} \sum_{i=1}^n (y_i-\hat{y}_i)^2 C=n1i=1∑n(yi−y^i)2
给定第一个结果,我们返回并调整权重和偏差,以便我们优化成本函数——称为后向传递。我们本质上是尝试调整整个神经网络,使输出值得到优化。从某种意义上说,这就是我们告诉算法它表现不佳或良好的方式。我们不断尝试通过从我们的数据集中运行新的观察来优化成本函数。
为了更新网络,我们计算所谓的梯度,它是对每一层中单个权重的微小推动(更新)。
∂ C ∂ w ( L ) = ∂ C ∂ a ( L ) ∂ a ( L ) ∂ z ( L ) ∂ z ( L ) ∂ w ( L ) \frac{\partial C}{\partial w^{(L)}} = \frac{\partial C}{\partial a^{(L)}} \frac{\partial a^{(L) }}{\partial z^{(L)}} \frac{\partial z^{(L)}}{\partial w^{(L)}} ∂w(L)∂C=∂a(L)∂C∂z(L)∂a(L)∂w(L)∂z(L)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yANs2g5B-1643446592651)(https://mlfromscratch.com/content/images/2019/12/overview-nn-optimized.gif)]
我们简单地遍历每个权重,例如在输出层,然后从特定权重的原始值中减去学习率的值乘以特定权重的成本。
w ( L ) = w ( L ) − 学习率 × ∂ C ∂ w ( L ) w^{(L)} = w^{(L)} - \text{学习率} \times \frac{\partial C}{\partial w^{(L)}} w(L)=w(L)−学习率×∂w(L)∂C
添加一些称为 mini-batch 的东西,我们平均每个 mini.batch 一些定义的观察的梯度,然后你就有了基本的神经网络设置。
如果您继续阅读,我将详细解释每个部分。如果您想阅读特定内容,请参阅目录。
我们从前馈神经网络开始,然后进入符号,然后深入解释反向传播,最后概述优化器如何帮助我们使用反向传播算法,特别是随机梯度下降。
什么是神经网络?
有很多术语要涵盖。让我一步一步来,然后你就需要坐稳了。
神经网络是一种受我们大脑神经元启发的算法。它旨在识别复杂数据中的模式,并且在识别音频、图像或视频中的模式时通常表现最佳。
神经元——连接
神经网络仅由神经元(也称为节点)组成。这些节点以某种方式连接。然后每个神经元都有一个数字,每个连接都有一个权重。
这些神经元分为输入层、隐藏层和输出层。在实践中,层数很多,没有一般的最佳层数。
白色圆圈对应于神经元,黄色箭头是从一个神经元到另一个神经元的**连接(带有权重) 。**上面的白框表示哪一层是哪一层。
这个想法是我们将数据输入到输入层,它通过不同的连接将数据中的数字从网络中的一个神经元乒乓球向前发送到另一个神经元。一旦我们到达输出层,我们希望得到我们想要的数字。
输入数据只是您的数据集,其中每个观察结果从 x = 1 , . . . , x = i x=1,...,x=i x=1,...,x=i 依次运行。每个神经元都有一些激活——一个介于 0 和 1 之间的值,其中 1 是最大激活,0 是神经元可以具有的最小激活。也就是说,如果我们使用称为 sigmoid 的激活函数,如下所述。因此,建议将数据缩放到 0 到 1 之间的值(例如,使用Scikit-Learn 中的 MinMaxScaler)。
从输入层到隐藏层
我们输入的数据集给了我们输入层,但是之后的层呢?所发生的只是大量的数字乒乓球,无非是基本的数学运算。我们查看输入层中的所有神经元,它们连接到下一层(隐藏层)中的新神经元。
**记住这一点:**每个神经元都有一个激活a,每个连接到一个新神经元的神经元都有一个权重w。激活通常是 0 到 1 范围内的数字,权重是双倍,例如 2.2、-1.2、0.4 等。
这是一个例子,假设我们有每个激活的值和一个新神经元的权重。
(参见随机梯度下降的权重解释)
**然后…**可以将激活乘以权重并在下一层得到一个神经元,从第一个权重和激活
w
1
a
1
w_1a_1
w1a1 一直到
w
n
a
n
w_na_n
wnan:
w 1 a 1 + w 2 a 2 + . . . + w n a n = 新神经元 w_1a_1+w_2a_2+...+w_na_n = \text{新神经元} w1a1+w2a2+...+wnan=新神经元
也就是说,乘以n个权重和激活,得到一个新神经元的值。
1.1 × 0.3 + 2.6 × 1.0 = 2.93 1.1 \times 0.3+2.6 \times 1.0 = 2.93 1.1×0.3+2.6×1.0=2.93
该过程在神经元网络中向前移动是相同的,因此称为前馈神经网络。
激活函数
但是…事情并没有那么简单。我们还有一个激活函数,最常见的是一个 sigmoid 函数,它只是将输出再次缩放到 0 和 1 之间——所以它是一个逻辑函数。在以后的帖子中,将发布许多激活函数的比较或演练。
sigmoid = σ = 1 1 + e − x = 0到1之间的数字 \text{sigmoid} = \sigma = \frac{1}{1+e^{-x}}= \text{0到1之间的数字} sigmoid=σ=1+e−x1=0到1之间的数字
我们用激活来包装新神经元的方程,即乘以权重和激活的结果的乘法总结
σ ( w 1 a 1 + w 2 a 2 + . . . + w n a n ) = 新神经元 \sigma(w_1a_1+w_2a_2+...+w_na_n) = \text{新神经元} σ(w1a1+w2a2+...+wnan)=新神经元
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rdic5FbR-1643446592658)(https://mlfromscratch.com/content/images/2019/12/0e5d1b75-6e20-4093-9457-2e7fb29f0592.png)]sigmoid 函数的图像。取一个输入 x,我们得到一个介于 0 和 1 之间的数字。
现在我们只需要解释在方程中添加一个偏差,然后你就有了计算新神经元值的基本设置。
Bias试图估计新神经元的值开始有意义的位置。因此,您将尝试从激活和权重的乘积中添加或减去偏差。
σ ( w 1 a 1 + w 2 a 2 + . . . + w n a n + b ) = 新神经元 \sigma(w_1a_1+w_2a_2+...+w_na_n + b) = \text{新神经元} σ(w1a1+w2a2+...+wnan+b)=新神经元
激活函数有很多种,这里是一个概述:
许多类型的激活函数,在以后的文章中解释。从这里。
这就是一个非常基本的神经网络,前馈神经网络的全部内容。但是我们需要在混合中引入其他算法,向您介绍这样的网络实际上是如何学习的。
在进入神经网络学习的核心之前,我们必须先谈谈符号。至少对我来说,一开始我对这个符号感到困惑,因为没有多少人花时间解释它。
神经网络的数学
在进入更高级的算法之前,我想提供一些神经网络的符号和一般数学知识——或者至少是它的资源,如果你不知道线性代数或微积分的话。
符号:线性代数
在学习神经网络理论的时候,经常会发现大部分的神经元和层都是用线性代数格式化的。请注意,我写了一个简短的系列文章,您可以在其中自下而上地学习线性代数。我建议阅读其中的大部分内容并尝试理解它们。如果您不这样做,请发表评论,我会尽力及时回答。
符号非常简洁,但也可能很麻烦。让我从最终方程的底部开始,然后解释我的方法到上一个方程:
σ ( w 1 a 1 + w 2 a 2 + . . . + w n a n ± b ) = 新神经元 \sigma(w_1a_1+w_2a_2+...+w_na_n\pm b) = \text{新神经元} σ(w1a1+w2a2+...+wnan±b)=新神经元
因此,我们首先将激活和权重组织到相应的矩阵中。
我们用 a n e u r o n ( l a y e r ) a_{neuron}^{(layer)} aneuron(layer) 表示每个激活,例如 a 2 ( 1 ) a_{2}^{(1)} a2(1) 将对应于第二层中的第三个神经元(我们从0 开始计数)。所以下面的数字(下标)对应我们说的是哪个神经元,上面的数字(上标)对应的是我们说的是哪一层,从零开始计数。
我们用 w t o , f r o m w_{to,from} wto,from 表示每个权重,其中to表示为 j j j,from表示为 k k k,例如 w 2 , 3 2 w_{2,3}^{2} w2,32 表示到第三层中的第三个神经元,来自上一层(第二层)的神经元四,因为我们从零开始计数。检查矩阵中的 w w w 也是有意义的,但我不会在这里详细介绍。
要计算下一层的每个激活,我们需要上一层的所有激活:
\begin{bmatrix} a_0^{0}\ a_1^{0}\ \vdots \ a_n^{0}\ \end{bmatrix}
以及连接到下一层每个神经元的所有权重:
\begin{bmatrix} w_{0,0} & w_{0,1} & \cdots & w_{0,k}\ w_{1,0} & w_{1,1} & \cdots & w_{1 ,k}\ \vdots & \vdots & \ddots & \vdots \ w_{j,0} & w_{j,1} & \cdots & w_{j,k}\ \end{bmatrix}
结合这两者,我们可以进行矩阵乘法(阅读我的帖子),添加一个偏置矩阵并将整个方程包装在 sigmoid 函数中,我们得到:
$ \sigma \left( \begin{bmatrix} w_{0,0} & w_{0,1} & \cdots & w_{0,k}\ w_{1,0} & w_{1,1} & \cdots & w_{1,k}\ \vdots & \vdots & \ddots & \vdots \ w_{j,0} & w_{j,1} & \cdots & w_{j,k}\ \ end{bmatrix} , \begin{bmatrix} a_0^{0}\ a_1^{0}\ \vdots \ a_n^{0}\ \end{bmatrix} + \begin{bmatrix} b_0\ b_1\ \vdots \ b_n\ \end{bmatrix} \right) $
这是最后的表达方式,如果你没有遵循的话,它很简洁,也许很麻烦。:
a ( 1 ) = σ ( W a 0 + b ) a^{(1)}= \sigma\left( \boldsymbol{W}\boldsymbol{a}^{0}+\boldsymbol{b} \right) a(1)=σ(Wa0+b)
有时我们甚至可以进一步减少符号并将 sigmoid 函数中的权重、激活和偏差替换为仅仅 z z z:
a ( 1 ) = σ ( z ) a^{(1)}= \sigma\left( \boldsymbol{z} \right) a(1)=σ(z)
要阅读它:
我们从第一层 a 0 \boldsymbol{a^{0}} a0 获取所有激活值,对连接每个神经元从第一层到第二层 W \boldsymbol{W} W 的所有权重进行矩阵乘法,添加一个偏置矩阵,最后对结果使用 sigmoid 函数 σ \sigma σ。由此,我们得到第二层中所有激活的矩阵。
微积分知识
你需要知道如何求切线的斜率——求函数的导数。在实践中,您实际上并不需要知道如何进行每个导数,但您至少应该对导数的含义有所了解。
有不同的微分规则,最重要和最常用的规则之一是链式法则,但这里列出了多种微分规则,如果你想在即将到来的算法中计算梯度,这很高兴。我们找到一个变量的导数并让其余变量保持不变的偏导数对于了解一些知识也很有价值。
我自己的观点是,你不需要能够做数学,你只需要能够理解这些算法背后的过程。我将挑选每个算法,以更深入地了解这些杰出算法背后的数学原理。
总而言之,您应该了解这些术语的含义,或者能够进行以下计算:
- 矩阵;矩阵乘法和加法,矩阵的符号。
- 衍生品;测量图表上斜率特定点的陡度。
- 偏导数;一个变量的导数,其余的都是常数。
- 链式法则;求两个或多个函数的组合。
现在你已经理解了这个符号,我们应该进入神经网络工作的核心。该算法是每个神经网络的一部分。当我分解它时,有一些数学,但不要害怕。如果您了解反向传播的总体情况,那么数学的作用实际上相当简单。
反向传播
反向传播是每个神经网络的核心。首先,我们需要区分反向传播和优化器(稍后会介绍)。
反向传播是为了有效地计算梯度,而优化器是为了训练神经网络,使用反向传播计算的梯度。简而言之,反向传播对我们所做的就是计算梯度。而已。
SO… Err,我们如何倒退?
我们总是从输出层开始向后传播,更新每一层的权重和偏差。
**这个想法很简单:**调整整个网络的权重和偏差,以便我们在输出层获得所需的输出。假设我们希望输出神经元为 1.0,那么我们需要微调权重和偏差,以使输出接近 1.0。
我们只能改变权重和偏差,但激活是对这些权重和偏差的直接计算,这意味着我们可以间接调整神经网络的每个部分,以获得所需的输出——除了输入层,因为那是数据集你输入的。
计算梯度
现在,在方程之前,让我们定义每个变量的含义。我们已经定义了其中的一些,但总结一下还是不错的。如果您阅读了这篇文章,您应该熟悉其中的一些内容。
请!注意 L、L-1 和l之间使用的符号。我故意把它混在一起,这样你就可以了解它们是如何工作的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FbavZCqb-1643446592673)(https://mlfromscratch.com/content/images/2019/12/v2.png)]较小的备忘单,包含本文中使用的所有符号
首先,让我们从定义相关方程开始。请注意,前面解释的任何索引都在这里省略了,我们抽象到每一层而不是每个权重、偏差或激活:
z ( L ) = w ( L ) × a + b z^{(L)}=w^{(L)} \times a +b z(L)=w(L)×a+b
a ( L ) = σ ( z ( L ) ) a^{(L)}= \sigma\left( \boldsymbol{z}^{(L)} \right) a(L)=σ(z(L))
C = ( a ( L ) − y ) 2 C=(a^{(L)}-y)^2 C=(a(L)−y)2
稍后将在成本函数部分详细介绍成本函数。
我们可能会通过思考这个问题来发现如何在反向传播算法中计算梯度:
我们如何衡量与特定权重、偏差或激活相关的成本函数变化?
在数学上,这就是我们需要了解偏导数的原因,因为它们允许我们计算神经网络组件与成本函数之间的关系。显而易见,我们希望最小化成本函数。当我们知道是什么影响它时,我们可以有效地改变相关的权重和偏差以最小化成本函数。
∂ C ∂ w ( L ) = ∂ C ∂ a ( L ) ∂ a ( L ) ∂ z ( L ) ∂ z ( L ) ∂ w ( L ) = 2 ( a ( L ) − y ) σ ′ ( z ( L ) ) a ( L − 1 ) \frac{\partial C}{\partial w^{(L)}} = \frac{\partial C}{\partial a^{(L)}} \frac{\partial a^{(L) }}{\partial z^{(L)}} \frac{\partial z^{(L)}}{\partial w^{(L)}} = 2 \left(a^{(L)} - y \right) \sigma' \left(z^{(L)}\right) a^{(L-1)} ∂w(L)∂C=∂a(L)∂C∂z(L)∂a(L)∂w(L)∂z(L)=2(a(L)−y)σ′(z(L))a(L−1)
如果你不是数学系的学生或者没有学过微积分,这点就不清楚了。所以让我试着把它说得更清楚。
压扁的“d”是偏导数符号。 ∂ C / ∂ w L \partial C/\partial w^{L} ∂C/∂wL 意味着我们查看成本函数 C C C,在其中我们只取 w L w^{L} wL 的导数,即剩下的变量照原样。我没有在本文中展示如何区分,因为有很多很好的资源。
虽然 w L w^{L} wL 不是直接在成本函数中找到,但我们首先考虑 z 方程中 w 的变化,因为 z 方程包含 w。接下来我们考虑 a L a^{L} aL中 z L z^{L} zL的变化,然后是函数 C C C中 a L a^{L} aL的变化。实际上,这测量了特定权重相对于成本函数的变化。
我们测量权重(和偏差)与成本函数之间的比率。比率最大的那些将对成本函数产生最大的影响,并将给我们带来“最大的收益”。
计算梯度的三个方程
我们需要在网络中向后移动并更新权重和偏差。让我们介绍如何用数学来做到这一点。一个权重方程,一个偏置方程,一个激活方程:
∂ C ∂ w ( L ) = ∂ C ∂ a ( L ) ∂ a ( L ) ∂ z ( L ) ∂ z ( L ) ∂ w ( L ) \frac{\partial C}{\partial w^{(L)}} = \frac{\partial C}{\partial a^{(L)}} \frac{\partial a^{(L) }}{\partial z^{(L)}} \frac{\partial z^{(L)}}{\partial w^{(L)}} ∂w(L)∂C=∂a(L)∂C∂z(L)∂a(L)∂w(L)∂z(L)
∂ C ∂ b ( L ) = ∂ C ∂ a ( L ) ∂ a ( L ) ∂ z ( L ) ∂ z ( L ) ∂ b ( L ) \frac{\partial C}{\partial b^{(L)}} = \frac{\partial C}{\partial a^{(L)}} \frac{\partial a^{(L) }}{\partial z^{(L)}} \frac{\partial z^{(L)}}{\partial b^{(L)}} ∂b(L)∂C=∂a(L)∂C∂z(L)∂a(L)∂b(L)∂z(L)
∂ C ∂ a ( L − 1 ) = ∂ C ∂ a ( L ) ∂ a ( L ) ∂ z ( L ) ∂ z ( L ) ∂ a ( L − 1 ) \frac{\partial C}{\partial a^{(L-1)}} = \frac{\partial C}{\partial a^{(L)}} \frac{\partial a^{( L)}}{\partial z^{(L)}} \frac{\partial z^{(L)}}{\partial a^{(L-1)}} ∂a(L−1)∂C=∂a(L)∂C∂z(L)∂a(L)∂a(L−1)∂z(L)
请记住,这些方程只是衡量特定权重如何影响我们想要优化的成本函数的比率。我们通过在这些方程的输出方向上逐步进行优化。它真的(几乎)那么简单。
权重和偏差的每个偏导数都保存在梯度向量中,该向量具有与权重和偏差一样多的维度。梯度是三角形符号 ∇ \nabla ∇,n是权重和偏差的数量:
− ∇ C ( w 1 , b 1 , . . . , w n , b n ) = [ ∂ C ∂ w 1 ∂ C ∂ b 1 ⋮ ∂ C ∂ w n ∂ C ∂ b n ] -\nabla C(w_1, b_1,..., w_n, b_n) = \begin{bmatrix} \frac{\partial C}{\partial w_1} \\ \frac{\partial C}{\partial b_1 } \\ \vdots \\ \frac{\partial C}{\partial w_n} \\ \frac{\partial C}{\partial b_n} \end{bmatrix} −∇C(w1,b1,...,wn,bn)=⎣⎢⎢⎢⎢⎢⎢⎡∂w1∂C∂b1∂C⋮∂wn∂C∂bn∂C⎦⎥⎥⎥⎥⎥⎥⎤
激活也是一个跟踪的好主意,以查看网络如何对变化做出反应,但我们不会将它们保存在梯度向量中。重要的是,它们还帮助我们衡量哪些权重最重要,因为权重乘以激活。从效率的角度来看,这对我们很重要。
您根据数据的小批量(通常 16 或 32 最好)计算梯度,即将观察结果分批进行二次抽样。对于小批量中的每个观察,您平均每个权重和偏差的输出。然后这些权重和偏差的平均值成为梯度的输出,这在小批量大小的平均最佳方向上创建了一个步骤。
然后,您将在每个 mini-batch 之后更新权重和偏差。对于每一层l ,每个权重和偏差都被“轻推”了一定的量:
w ( l ) = w ( l ) − 学习率 × ∂ C ∂ w ( l ) w^{(l)} = w^{(l)} - \text{学习率} \times \frac{\partial C}{\partial w^{(l)}} w(l)=w(l)−学习率×∂w(l)∂C
b ( l ) = b ( l ) − 学习率 × ∂ C ∂ b ( l ) b^{(l)} = b^{(l)} - \text{学习率} \times \frac{\partial C}{\partial b^{(l)}} b(l)=b(l)−学习率×∂b(l)∂C
学习率通常写成 alpha α \alpha α 或 eta η \eta η。
但这还不是全部。我展示的三个方程仅用于输出层,如果我们要通过网络向后移动一层,则每个权重、偏差和激活都会有更多的偏导数需要计算。我们必须通过网络一直向后移动并调整每个权重和偏差。
示例:深入
考虑到其余的层,我们必须链接更多的偏导数来找到第一层的权重,但我们不需要计算其他任何东西。
如果我们查看前面示例中的隐藏层,我们将不得不使用之前的偏导数以及两个新计算的偏导数。为了帮助您了解原因,您应该查看下面的依赖关系图,因为它有助于解释每一层对先前权重和偏差的依赖关系。
用于计算梯度的依赖项。第 1 层依赖于第 2 层,因为它重用了第 2 层的梯度计算
更新第 2 层(或 L L L)中的权重和偏差仅取决于成本函数,以及连接到第 2 层的权重和偏差。类似地,对于更新第 1 层(或 L − 1 L-1 L−1),依赖项是第 2 层的计算以及第 1 层的权重和偏差。如果我们有更多的层,就会有更多的依赖关系。您可能会发现,这就是我们称之为“反向传播”的原因。
如上图所示,要计算连接到隐藏层的权重,我们将不得不重用之前对输出层(L 或第 2 层)的计算。让我提醒他们:
∂ C ∂ w ( 2 ) = ∂ C ∂ a ( 2 ) ∂ a ( 2 ) ∂ z ( 2 ) ∂ z ( 2 ) ∂ w ( 2 ) \frac{\partial C}{\partial w^{(2)}} = \frac{\partial C}{\partial a^{(2)}} \frac{\partial a^{(2) }}{\partial z^{(2)}} \frac{\partial z^{(2)}}{\partial w^{(2)}} ∂w(2)∂C=∂a(2)∂C∂z(2)∂a(2)∂w(2)∂z(2)
∂ C ∂ b ( 2 ) = ∂ C ∂ a ( 2 ) ∂ a ( 2 ) ∂ z ( 2 ) ∂ z ( 2 ) ∂ b ( 2 ) \frac{\partial C}{\partial b^{(2)}} = \frac{\partial C}{\partial a^{(2)}} \frac{\partial a^{(2) }}{\partial z^{(2)}} \frac{\partial z^{(2)}}{\partial b^{(2)}} ∂b(2)∂C=∂a(2)∂C∂z(2)∂a(2)∂b(2)∂z(2)
如果我们想计算连接到隐藏层(L-1 或第 1 层)的权重和偏差的更新,我们将不得不重用之前的一些计算。
KaTeX parse error: Undefined control sequence: \部 at position 192: …)}}$} \, \frac{\̲部̲分 z^{(2)}}{\par…
KaTeX parse error: Undefined control sequence: \部 at position 192: …)}}$} \, \frac{\̲部̲分 z^{(2)}}{\par…
我们使用所有先前的计算,除了关于层的权重或偏差的偏导数,例如我们不重用 ∂ z ( 1 ) / ∂ w ( 1 ) \partial z^{(1)}/ \partial w^{(1)} ∂z(1)/∂w(1) (我们显然使用了一些 ∂ C / ∂ w ( 1 ) \partial C/\partial w^{(1)} ∂C/∂w(1))。
如果您查看上面的依赖关系图,您可以将最后两个等式连接到左侧的*“Layer 1 Dependencies”*的大花括号。尝试通过链接图中的 L-1 层来理解使用的符号。这应该使事情更清楚,如果您有疑问,请发表评论。
这里遗漏的一个小细节是,如果你先计算权重,那么你可以重用 4 个一阶偏导数,因为在计算偏差的更新时它们是相同的。当然反过来。
假设我们有另一个隐藏层,也就是说,如果我们有输入-隐藏-隐藏-输出——总共有四层。然后我们将重用之前的计算来更新前一层。我们基本上对每一层的每个权重和偏差都这样做,重用计算。
所以…如果我们假设我们有一个额外的隐藏层,方程将如下所示:
∂ C ∂ w ( 1 ) = ∂ C ∂ a ( 3 ) ∂ a ( 3 ) ∂ z ( 3 ) ⏟ From w ( 3 ) ∂ z ( 3 ) ∂ a ( 2 ) ∂ a ( 2 ) ∂ z ( 2 ) ⏟ 来自 w ( 2 ) ∂ z ( 2 ) ∂ a ( 1 ) ∂ a ( 1 ) ∂ z ( 1 ) ∂ z ( 1 ) ∂ w ( 1 ) \frac{\partial C}{\partial w^{(1)}} = \underbrace{ \frac{\partial C}{\partial a^{(3)}} \frac{\partial a^{ (3)}}{\partial z^{(3)}} }_\text{From $w^{(3)}$} \, \underbrace{ \frac{\partial z^{(3)}} {\partial a^{(2)}} \frac{\partial a^{(2)}}{\partial z^{(2)}} }_\text{来自$w^{(2)}$ } \, \frac{\partial z^{(2)}}{\partial a^{(1)}} \frac{\partial a^{(1)}}{\partial z^{(1)} } \frac{\partial z^{(1)}}{\partial w^{(1)}} ∂w(1)∂C=From w(3) ∂a(3)∂C∂z(3)∂a(3)来自w(2) ∂a(2)∂z(3)∂z(2)∂a(2)∂a(1)∂z(2)∂z(1)∂a(1)∂w(1)∂z(1)
如果您正在寻找具有明确数字的具体示例,我建议您观看7:55 到 20:33 的 Lex Fridman或Andrej Karpathy 关于反向传播的讲座。
总结
- 在这个方程的帮助下做一个前传
a ( l ) = σ ( W a l − 1 + b ) a^{(l)}= \sigma\left( \boldsymbol{W}\boldsymbol{a}^{l-1}+\boldsymbol{b} \right) a(l)=σ(Wal−1+b)
- 对于连接到新层的每一层权重和偏差,通过这些方程使用反向传播算法进行反向传播(在计算偏差时将 w w w 替换为 b b b)
∂ C ∂ w ( 3 ) = ∂ C ∂ a ( 3 ) ∂ a ( 3 ) ∂ z ( 3 ) ∂ z ( 3 ) ∂ w ( 3 ) \frac{\partial C}{\partial w^{(3)}} = \frac{\partial C}{\partial a^{(3)}} \frac{\partial a^{(3) }}{\partial z^{(3)}} \frac{\partial z^{(3)}}{\partial w^{(3)}} ∂w(3)∂C=∂a(3)∂C∂z(3)∂a(3)∂w(3)∂z(3)
∂ C ∂ w ( 2 ) = ∂ C ∂ a ( 3 ) ∂ a ( 3 ) ∂ z ( 3 ) ⏟ 来自 w ( 3 ) ∂ z ( 3 ) ∂ a ( 2 ) ∂ a ( 2 ) ∂ z ( 2 ) ∂ z ( 2 ) ∂ w ( 2 ) \frac{\partial C}{\partial w^{(2)}} = \underbrace{ \frac{\partial C}{\partial a^{(3)}} \frac{\partial a^{ (3)}}{\partial z^{(3)}} }_\text{来自 $w^{(3)}$} \, \frac{\partial z^{(3)}}{\partial a^{(2)}} \frac{\partial a^{(2)}}{\partial z^{(2)}} \frac{\partial z^{(2)}}{\partial w^ {(2)}} ∂w(2)∂C=来自 w(3) ∂a(3)∂C∂z(3)∂a(3)∂a(2)∂z(3)∂z(2)∂a(2)∂w(2)∂z(2)
∂ C ∂ w ( 1 ) = ∂ C ∂ a ( 3 ) ∂ a ( 3 ) ∂ z ( 3 ) ⏟ From w ( 3 ) ∂ z ( 3 ) ∂ a ( 2 ) ∂ a ( 2 ) ∂ z ( 2 ) ⏟ 来自 w ( 2 ) ∂ z ( 2 ) ∂ a ( 1 ) ∂ a ( 1 ) ∂ z ( 1 ) ∂ z ( 1 ) ∂ w ( 1 ) \frac{\partial C}{\partial w^{(1)}} = \underbrace{ \frac{\partial C}{\partial a^{(3)}} \frac{\partial a^{ (3)}}{\partial z^{(3)}} }_\text{From $w^{(3)}$} \, \underbrace{ \frac{\partial z^{(3)}} {\partial a^{(2)}} \frac{\partial a^{(2)}}{\partial z^{(2)}} }_\text{来自$w^{(2)}$ } \, \frac{\partial z^{(2)}}{\partial a^{(1)}} \frac{\partial a^{(1)}}{\partial z^{(1)} } \frac{\partial z^{(1)}}{\partial w^{(1)}} ∂w(1)∂C=From w(3) ∂a(3)∂C∂z(3)∂a(3)来自w(2) ∂a(2)∂z(3)∂z(2)∂a(2)∂a(1)∂z(2)∂z(1)∂a(1)∂w(1)∂z(1)
以与此处相同的方式继续为每个额外层添加更多偏导数。
- 对每个观察/样本(或大小小于 32 的小批量)重复
优化器
优化器是神经网络学习的方式,使用反向传播来计算梯度。
许多因素会影响模型的性能。我们衡量性能的方式,对某些人来说可能很明显,是通过成本函数。
成本函数
成本函数为我们提供了一个我们想要优化的值。成本函数太多,无法一一提及,但其中一种更简单且经常使用的成本函数是平方差之和。
C = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 C = \frac{1}{n} \sum_{i=1}^n (y_i-\hat{y}_i)^2 C=n1i=1∑n(yi−y^i)2
其中 y y y 是我们想要的输出, y ^ \hat{y} y^ 是神经网络的实际预测输出。基本上,对于每个样本 n n n,我们从第一个示例 i = 1 i=1 i=1 开始求和,并在我们想要的输出 y y y 和每个样本的预测输出 y ^ \hat{y} y^ 之间的差异的所有平方上求和观察。
显然,有许多因素会影响特定神经网络的性能。模型的复杂性、超参数(学习率、激活函数等)、数据集的大小等等。
随机梯度下降
在随机梯度下降中,我们采用小批量随机样本,并根据小批量的平均梯度对权重和偏差进行更新。每个小批量的权重被随机初始化为一个小的值,例如 0.1。偏差以许多不同的方式初始化;最简单的初始化为0。
- 定义一个成本函数,以向量作为输入(权重或偏置向量)
- 从沿 x 轴的随机点开始,向任意方向步进。
问,我们应该采取哪种方式来最快地降低成本函数? - 如前所述,使用反向传播计算梯度
- 沿着梯度的相反方向前进——我们计算梯度上升,因此我们只需在方程前面加上一个减号或沿相反方向移动,使其梯度下降。
从下面的 GIF 中可以很容易地掌握随机梯度下降的样子。您在图表上看到的每个步骤都是梯度下降步骤,这意味着我们使用反向传播计算了一定数量样本的梯度,以沿一个方向移动。
如果偏导数的梯度是正的,我们向左走,否则我们在负的时候向右走。来自3blue1brown 视频的 GIF 动画并添加了字幕。
我们说我们想要达到一个全局最小值,即函数的最低点。但是,这并不总是可能的。我们很可能会达到局部最小值,即左右两侧向上移动的斜率之间的点。如果我们找到一个最小值,我们就说我们的神经网络已经收敛。如果我们不这样做,或者我们看到性能出现奇怪的下降,我们就说神经网络已经发散了。
如果我们计算正导数,我们在斜率上向左移动,如果为负,我们向右移动,直到我们处于局部最小值。
将神经网络逐步推进
在这里,我将简要地将神经网络的工作分解为更小的步骤。
对每个小批量重复:
- 将权重初始化为一个小的随机数,并让所有偏差为 0
- 开始小批量下一个样本的前向传递,并使用计算激活的方程进行前向传递
a ( l ) = σ ( W a l − 1 + b ) a^{(l)}=\sigma\left(\boldsymbol{W}\boldsymbol{a}^{l-1 }+\boldsymbol{b}\right) a(l)=σ(Wal−1+b) - 通过神经网络向后迭代传播计算梯度和更新梯度向量(小批量更新的平均值)。
输入-隐藏-隐藏-输出神经网络(4 层) $\frac{\partial C}{\partial w^{(1)}} = \underbrace{中 w 1 w^1 w1 偏导数的示例计算\frac{\partial C}{\partial a^{(3)}} \frac{\partial a^{(3)}}{\partial z^{(3)}} }\text{来自 w ( 3 ) w ^{(3)} w(3)} , \underbrace{ \frac{\partial z^{(3)}}{\partial a^{(2)}} \frac{\partial a^{(2)}} {\partial z^{(2)}} }\text{来自 w ( 2 ) w^{(2)} w(2)} , \frac{\partial z^{(2)}}{\partial a^{(1 )}} \frac{\partial a^{(1)}}{\partial z^{(1)}} \frac{\partial z^{(1)}}{\partial w^{(1)} }$ - 在梯度向量前面加上一个减号,并根据通过对小批量微调进行平均计算得出的梯度向量更新权重和偏差。
看完这篇文章了吗?去阅读优化器解释!
优化器解释 - 亚当、动量和随机梯度下降选择具有正确参数的正确优化器,可以帮助您从神经网络模型中挤出最后一点准确性。卡斯帕汉森从零开始机器学习
进一步阅读
最推荐的书是第一个要点。它将带您了解最新和最伟大的内容,同时详细解释概念,同时保持实用性。如果您是初学者或半初学者,这可能是开始学习的最佳书籍。
- 最佳实用书籍(推荐):
第 1版:Aurélion Géron 的动手机器学习(兼容 Kindle)
预购第 2版: Aurélien Géron 的动手机器学习
(使用 Scikit-Learn、Keras 和 TensorFlow:概念,构建智能系统的工具和技术) - 对数学和代码进行精确解释的
好书:Andriy Burkov 的百页机器学习书 - 被认为是最好的书籍之一:Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 的深度学习。这个可能比上一个更学术,更麻烦一点。尽管如此,这是一本好书。
- 我读过的一本好书:Michael Nielsen 的《神经网络和深度学习》 。他把事情解释清楚,把那些讨厌的数学方程分开,这样你就可以理解了。
有任何问题吗?在下面发表评论。我是来回答或澄清任何事情的。
更多 深度学习
-
使用深度学习应对 COVID-19
2020 年 4 月 21 日– 17 分钟阅读
-
使用 NumPy 和 MNIST 从零开始的神经网络
2020 年 3 月 19 日– 18 分钟阅读
-
TensorFlow 2.0 10 分钟教程
2019 年 11 月 6 日– 19 分钟阅读
深度学习激活函数解释 - GELU、SELU、ELU、ReLU 等更好的优化神经网络;选择正确的激活函数,你的神经网络可以表现得更好。解释了 6 个激活函数。
标签:partial,权重,前馈,神经网络,反向,frac,我们,神经元 来源: https://blog.csdn.net/weixin_45276304/article/details/122745352