深度学习基础--梯度下降与初始化

在神经网络的背景下,它们用于寻找能够最小化损失函数的参数,使模型能够根据输入准确预测训练数据的输出。基本方法是随机选择一组初始参数,然后逐步进行微小调整,平均而言这些调整会降低损失。每一次的调整都是基于当前参数位置对损失函数梯度的计算结果。

本章将讨论两个神经网络特有的问题。首先,我们将探讨如何高效地计算梯度,其次,我们讨论如何进行参数的初始化。如果初始化过程不被妥善处理,初始的损失及其梯度可能会非常大或非常小,这在任何情况下都将阻碍训练过程。

7.1 问题定义

考虑一个网络 f ( x , ϕ ) f(x, \phi) f(x,ϕ),它接受多变量输入 x x x,具有参数 ϕ \phi ϕ,并包含三个隐藏层 h 1 , h 2 h_1, h_2 h1,h2 h 3 h_3 h3

h 1 = a ( β 0 + Ω 0 x ) h 2 = a ( β 1 + Ω 1 h 1 ) h 3 = a ( β 2 + Ω 2 h 2 ) f ( x , ϕ ) = β 3 + Ω 3 h 3 (7.1) \begin{align} h_1 = a(\beta_0 + \Omega_0x) \\ h_2 = a(\beta_1 + \Omega_1h_1) \\ h_3 = a(\beta_2 + \Omega_2h_2) \\ f(x, \phi) = \beta_3 + \Omega_3h_3 \end{align} \tag{7.1} h1=a(β0+Ω0x)h2=a(β1+Ω1h1)h3=a(β2+Ω2h2)f(x,ϕ)=β3+Ω3h3(7.1)

其中激活函数 a [ ⋅ ] a[\cdot] a[] 分别作用于输入的每个元素。模型参数 ϕ = { β 0 , Ω 0 , β 1 , Ω 1 , β 2 , Ω 2 , β 3 , Ω 3 } \phi = \{\beta_0,\Omega_0,\beta_1,\Omega_1,\beta_2,\Omega_2,\beta_3,\Omega_3\} ϕ={ β0,Ω0,β1,Ω1,β2,Ω2,β3,Ω3} 包括每层之间的偏置向量 β k \beta_k βk 和权重矩阵 Ω k \Omega_k Ωk(见图 7.1)。

在这里插入图片描述
图 7.1 反向传播过程中的正向传播阶段。目的是计算损失 l 对于每个权重(用箭头表示)和偏置(图中未展示)的导数。也就是说,我们希望了解每个参数的微小变化将如何影响损失。每个权重将其源头的隐藏单元的激活值乘以权重值,并将结果传递给目标隐藏单元。因此,任何权重的微小变化所产生的效果,都会根据源隐藏单元的激活水平而放大。比如,蓝色权重作用于第一层的第二个隐藏单元;如果该单元的激活值增加一倍,那么对蓝色权重的微小变化产生的影响也会相应增加一倍。因此,为了计算权重的导数,我们需要计算并记录下隐藏层的激活值。这一过程称为正向传播,因为它包括了按顺序执行网络方程的过程。

此外,我们定义了单个损失项 l i l_i li 来返回基于模型预测 f ( x i , ϕ ) f(x_i, \phi) f(xi,ϕ) 对训练输入 x i x_i xi 的真实标签 y i y_i yi 的负对数似然。例如,这可能是指最小平方损失 l i = ( f ( x i , ϕ ) − y i ) 2 l_i = (f(x_i, \phi) - y_i)^2 li=(f(xi,ϕ)yi)2。总损失是所有训练数据上这些损失项的和:

L ( ϕ ) = ∑ i = 1 I l i (7.2) L(\phi) = \sum_{i=1}^{I} l_i \tag{7.2} L(ϕ)=i=1Ili(7.2)

对于训练神经网络,最常用的优化方法是随机梯度下降(SGD),通过以下方式更新参数:

ϕ t + 1 ← ϕ t − α ∑ i ∈ B t ∂ L ( i , ϕ t ) ∂ ϕ (7.3) \phi_{t+1} \leftarrow \phi_t - \alpha \sum_{i \in B_t} \frac{\partial \mathcal{L}(i,\phi_t)}{\partial \phi} \tag{7.3} ϕt+1ϕtαiBtϕL(i,ϕt)(7.3)

其中 α \alpha α 表示学习率, B t B_t Bt 为迭代 t t t 时的批次索引。要执行此更新,必须计算每个批次中索引 i i i 对应的参数 { β k , Ω k } \{\beta_k, \Omega_k\} { βk,Ωk} 在每一层 k ∈ { 0 , 1 , … , K } k \in \{0, 1, \ldots, K\} k{ 0,1,,K} 的导数:

∂ l i ∂ β k , and ∂ l i ∂ Ω k (7.4) \frac{\partial l_i}{\partial \beta_k}, \quad \text{and} \quad \frac{\partial l_i}{\partial \Omega_k} \tag{7.4} βkli,andΩkli(7.4)

本章的首部分阐述了反向传播算法,该算法能够高效地计算上述导数。

在章节的第二部分,我们将讨论在训练开始前如何初始化网络参数。我们将介绍方法来选择初始权重 Ω k \Omega_k Ωk 和偏置 β k \beta_k βk,确保训练过程的稳定性。

7.2 计算导数

损失函数的导数揭示了,当我们对模型参数进行细微调整时,损失值会如何变化。优化算法借此信息调整参数,以减少损失值。反向传播算法负责计算这些导数。鉴于涉及的数学细节较为复杂,我们先提出两个观点来帮助理解。

观察 1: 每一个权重(属于 Ω k \Omega_k Ωk)都会乘上某个源隐藏单元的激活值,并将结果累加到下一层的目标隐藏单元中。这意味着,权重的任意微小调整都会受到源隐藏单元激活值的放大或衰减作用。因此,我们会对每批数据中的每个样本运行网络,并记录所有隐藏单元的激活值。这个过程称为 前向传播(图 7.1)。记录下来的激活值之后将用于梯度的计算。

观察 2: 对偏置或权重的微小调整会在后续网络中引发一系列变化,这种变化会修改其目标隐藏单元的值。这又会导致下一层隐藏单元的值发生变化,接着是下下层,依此类推,直至模型输出和最终的损失值发生变化。

因此,要了解参数变化如何影响损失值,我们还需要知道每个后续隐藏层的变化如何进一步影响它们的后继层。这一逻辑同样适用于考虑同一或更早层次中的其他参数时。这意味着,我们可以一次性计算这些量,并在需要时复用。例如,设想计算对输入至隐藏层 h 3 h_3 h3 h 2 h_2 h2 h 1 h_1 h1 的权重进行微小调整的影响:

  • 要计算对隐藏层 h 3 h_3 h3 输入的权重或偏置的微小调整如何影响损失,我们需要知道 (i) h 3 h_3 h3 层变化如何影响模型输出 f f f,以及 (ii) 模型输出的变化如何影响损失(图 7.2a)。
  • 要计算对隐藏层 h 2 h_2 h2 输入的权重或偏置的微小调整如何影响损失,我们需要知道 (i) h 2 h_2 h2 层的变化如何影响 h 3 h_3 h3 层,(ii) h 3 h_3 h3 层的变化如何影响模型输出,以及 (iii) 模型输出的变化如何影响损失(图 7.2b)。
  • 要计算对隐藏层 h 1 h_1 h1 输入的权重或偏置的微小调整如何影响损失,我们需要知道 (i) h 1 h_1 h1 层的变化如何影响 h 2 h_2 h2 层,(ii) h 2 h_2 h2 层的变化如何影响 h 3 h_3 h3 层,(iii) h 3 h_3 h3 层的变化如何影响模型输出,以及 (iv) 模型输出的变化如何影响损失(图 7.2c)。

随着我们向网络的前端回溯,大部分必需的计算在前一步已经完成,因此无需重复计算。这种沿网络反向进行的计算导数的过程称为 反向传播

在这里插入图片描述
图 7.2 反向传播过程中的反向传播阶段。a) 为了计算对第三层 h3(蓝色箭头指向的层)输入权重的改变如何影响损失,我们需要知道 h3 中的隐藏单元如何影响模型输出 f,以及 f 如何影响损失(橙色箭头指示的影响)。b) 为了计算对第二层 h2(蓝色箭头指向的层)输入权重的微小改变如何影响损失,我们需要了解 (i) h2 中的隐藏单元如何影响 h3,(ii) h3 如何影响 f,以及 (iii) f 如何影响损失(橙色箭头指示的影响)。c) 类似地,为了计算对第一层 h1(蓝色箭头指向的层)输入权重的微小改变如何影响损失,我们需要知道 h1 如何影响 h2,以及这些变化如何通过网络传递影响到损失(橙色箭头指示的影响)。反向传播首先在网络末端计算导数,然后逆向进行,以此利用这些计算过程中的固有重复性。

虽然反向传播的概念相对容易理解,但其推导过程需要应用矩阵微积分,因为偏置和权重分别以向量和矩阵的形式存在。为了更好地理解其底层机理,下一节将为一个参数为标量的简化模型推导反向传播过程。之后,在第 7.4 节,我们将这一方法应用于深度神经网络。

7.3 示例

考虑一个含有八个标量参数 ϕ = [ β 0 , ω 0 , β 1 , ω 1 , β 2 , ω 2 , β 3 , ω 3 ] \phi = [\beta_0, \omega_0, \beta_1, \omega_1, \beta_2, \omega_2, \beta_3, \omega_3] ϕ=[β0,ω0,β1,ω1,β2,ω2,β3,ω3] 的模型 f ( x i , ϕ ) f(x_i, \phi) f(xi,ϕ),该模型是通过组合 sin ⁡ [ ⋅ ] \sin[\cdot] sin[] exp ⁡ [ ⋅ ] \exp[\cdot] exp[] cos ⁡ [ ⋅ ] \cos[\cdot] cos[] 函数而构成的:

f ( x , ϕ ) = β 3 + ω 3 ⋅ cos ⁡ [ β 2 + ω 2 ⋅ exp ⁡ [ β 1 + ω 1 ⋅ sin ⁡ [ β 0 + ω 0 ⋅ x ] ] ] (7.5) f(x, \phi) = \beta_3 + \omega_3 \cdot \cos[\beta_2 + \omega_2 \cdot \exp[\beta_1 + \omega_1 \cdot \sin[\beta_0 + \omega_0 \cdot x]]] \tag{7.5} f(x,ϕ)=β3+ω3cos[β2+ω2exp[β1+ω1sin[β0+ω0x]]](7.5)
以及一个最小二乘损失函数 L [ ϕ ] = ∑ i ℓ i L[\phi] = \sum_i \ell_i L[ϕ]=ii,其中的每一项定义如下:
ℓ i = ( f ( x i , ϕ ) − y i ) 2 (7.6) \ell_i = (f(x_i, \phi) - y_i)^2 \tag{7.6} i=(f(xi,ϕ)yi)2(7.6)

其中,按照惯例, x i x_i xi 表示第 i i i 个训练输入, y i y_i yi 表示第 i i i 个训练输出。可以把这看作是一个简单的神经网络,它具有单个输入、单个输出、每层一个隐藏单元,并且每一层之间采用了不同的激活函数 sin ⁡ [ ⋅ ] \sin[\cdot] sin[] exp ⁡ [ ⋅ ] \exp[\cdot] exp[] cos ⁡ [ ⋅ ] \cos[\cdot] cos[]。我们的目标是计算以下导数:

∂ ℓ i ∂ ω 0 , ∂ ℓ i ∂ β 1 , ∂ ℓ i ∂ ω 1 , ∂ ℓ i ∂ β 2 , ∂ ℓ i ∂ ω 2 , ∂ ℓ i ∂ β 3 ,  和  ∂ ℓ i ∂ ω 3 . \frac{\partial \ell_i}{\partial \omega_0}, \frac{\partial \ell_i}{\partial \beta_1}, \frac{\partial \ell_i}{\partial \omega_1}, \frac{\partial \ell_i}{\partial \beta_2}, \frac{\partial \ell_i}{\partial \omega_2}, \frac{\partial \ell_i}{\partial \beta_3}, \text{ 和 } \frac{\partial \ell_i}{\partial \omega_3}. ω0i,β1i,ω1i,β2i,ω2i,β3i,  ω3i.

虽然我们理论上可以通过手工求解这些导数的表达式并直接计算它们,但是部分导数表达式的复杂度相当高。举个例子:

∂ ℓ i ∂ ω 0 = − 2 [ ( β 3 + ω 3 ⋅ cos ⁡ [ β 2 + ω 2 ⋅ exp ⁡ [ β 1 + ω 1 ⋅ sin ⁡ [ β 0 + ω 0 ⋅ x i ] ] ] − y i ) ⋅ ω 1 ω 2 ω 3 ⋅ x i ⋅ cos ⁡ [ β 0 + ω 0 ⋅ x i ] ⋅ exp ⁡ [ β 1 + ω 1 ⋅ sin ⁡ [ β 0 + ω 0 ⋅ x i ] ] ⋅ sin ⁡ [ β 2 + ω 2 ⋅ exp ⁡ [ β 1 + ω 1 ⋅ sin ⁡ [ β 0 + ω 0 ⋅ x i ] ] ] ] (7.7) \frac{\partial \ell_i}{\partial \omega_0} = -2 \left[ (\beta_3 + \omega_3 \cdot \cos[\beta_2 + \omega_2 \cdot \exp[\beta_1 + \omega_1 \cdot \sin[\beta_0 + \omega_0 \cdot x_i]]] - y_i) \right. \\ \cdot \omega_1 \omega_2 \omega_3 \cdot x_i \cdot \cos[\beta_0 + \omega_0 \cdot x_i] \cdot \exp[\beta_1 + \omega_1 \cdot \sin[\beta_0 + \omega_0 \cdot x_i]] \\ \left. \cdot \sin[\beta_2 + \omega_2 \cdot \exp[\beta_1 + \omega_1 \cdot \sin[\beta_0 + \omega_0 \cdot x_i]]] \right] \tag{7.7} ω0i=2[(β3+ω3cos[β2+ω2exp[β1+ω1sin[β0+ω0xi]]]yi)ω1ω2ω3xicos[β0+ω0xi]exp[β1+ω1sin[β0+ω0xi]]sin[β2+ω2exp[β1+ω1sin[β0+ω0xi]]]](7.7)

这些表达式的推导和编码不仅容易出错,而且未能充分利用其中的重复性元素;值得注意的是,三个指数函数项实际上是一致的。

反向传播算法是一种同时计算所有这些导数的高效方法,它主要分为两个步骤:(i)前向传播,在此过程中我们计算并保存一系列中间值及网络的输出结果;(ii)反向传播,在此过程中我们从网络的输出层开始,逆向计算每个参数的导数,同时复用之前阶段的计算结果。

前向传播: 我们把损失计算过程视作一连串的计算步骤:

f 0 = β 0 + ω 0 ⋅ x i h 1 = sin ⁡ [ f 0 ] f 1 = β 1 + ω 1 ⋅ h 1 h 2 = exp ⁡ [ f 1 ] f 2 = β 2 + ω 2 ⋅ h 2 h 3 = cos ⁡ [ f 2 ] f 3 = β 3 + ω 3 ⋅ h 3 ℓ i = ( f 3 − y i ) 2 . (7.8) \begin{align*} f_0 &= \beta_0 + \omega_0 \cdot x_i \\ h_1 &= \sin[f_0] \\ f_1 &= \beta_1 + \omega_1 \cdot h_1 \\ h_2 &= \exp[f_1] \\ f_2 &= \beta_2 + \omega_2 \cdot h_2 \\ h_3 &= \cos[f_2] \\ f_3 &= \beta_3 + \omega_3 \cdot h_3 \\ \ell_i &= (f_3 - y_i)^2. \end{align*} \tag{7.8} f0h1f1h2f2h3f3i=β0+ω0xi=sin[f0]=β1+ω1h1=exp[f1]=β2+ω2h2=cos[f2]=β3+ω3h3=(f3yi)2.(7.8)

我们计算并存储了中间变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值