专业建网站价格,wordpress识别环境的文件夹,深圳logo设计公司排名,全案设计公司名字注#xff1a;书中对代码的讲解并不详细#xff0c;本文对很多细节做了详细注释。另外#xff0c;书上的源代码是在Jupyter Notebook上运行的#xff0c;较为分散#xff0c;本文将代码集中起来#xff0c;并加以完善#xff0c;全部用vscode在python 3.9.18下测试通过。…注书中对代码的讲解并不详细本文对很多细节做了详细注释。另外书上的源代码是在Jupyter Notebook上运行的较为分散本文将代码集中起来并加以完善全部用vscode在python 3.9.18下测试通过。
Chapter4 Multilayer Perceptron
4.8 Numerical Stability and Model Initialization
4.8.1 Gradient Vanishing and Gradient Exploding
考虑一个具有 L L L层、输入 x \mathbf{x} x和输出 o \mathbf{o} o的深层网络。每一层 l l l由变换 f l f_l fl定义该变换的参数为权重 W ( l ) \mathbf{W}^{(l)} W(l)其隐藏变量是 h ( l ) \mathbf{h}^{(l)} h(l)令 h ( 0 ) x \mathbf{h}^{(0)} \mathbf{x} h(0)x。我们的网络可以表示为 h ( l ) f l ( h ( l − 1 ) ) 因此 o f L ∘ … ∘ f 1 ( x ) . \mathbf{h}^{(l)} f_l (\mathbf{h}^{(l-1)}) \text{ 因此 } \mathbf{o} f_L \circ \ldots \circ f_1(\mathbf{x}). h(l)fl(h(l−1)) 因此 ofL∘…∘f1(x).
如果所有隐藏变量和输入都是向量我们可以将 o \mathbf{o} o关于任何一组参数 W ( l ) \mathbf{W}^{(l)} W(l)的梯度写为下式 ∂ W ( l ) o ∂ h ( L − 1 ) h ( L ) ⏟ M ( L ) d e f ⋅ … ⋅ ∂ h ( l ) h ( l 1 ) ⏟ M ( l 1 ) d e f ∂ W ( l ) h ( l ) ⏟ v ( l ) d e f . \partial_{\mathbf{W}^{(l)}} \mathbf{o} \underbrace{\partial_{\mathbf{h}^{(L-1)}} \mathbf{h}^{(L)}}_{ \mathbf{M}^{(L)} \stackrel{\mathrm{def}}{}} \cdot \ldots \cdot \underbrace{\partial_{\mathbf{h}^{(l)}} \mathbf{h}^{(l1)}}_{ \mathbf{M}^{(l1)} \stackrel{\mathrm{def}}{}} \underbrace{\partial_{\mathbf{W}^{(l)}} \mathbf{h}^{(l)}}_{ \mathbf{v}^{(l)} \stackrel{\mathrm{def}}{}}. ∂W(l)oM(L)def ∂h(L−1)h(L)⋅…⋅M(l1)def ∂h(l)h(l1)v(l)def ∂W(l)h(l).
换言之该梯度是 L − l L-l L−l个矩阵 M ( L ) ⋅ … ⋅ M ( l 1 ) \mathbf{M}^{(L)} \cdot \ldots \cdot \mathbf{M}^{(l1)} M(L)⋅…⋅M(l1)与梯度向量 v ( l ) \mathbf{v}^{(l)} v(l)的乘积。矩阵 M ( l ) \mathbf{M}^{(l)} M(l) 可能具有各种各样的特征值。他们可能很小也可能很大他们的乘积可能非常大也可能非常小。
不稳定梯度也威胁到我们优化算法的稳定性。要么是梯度爆炸gradient exploding问题参数更新过大破坏了模型的稳定收敛要么是梯度消失gradient vanishing问题参数更新过小在每次更新时几乎不会移动导致模型无法学习。
4.8.1.1 Gradient Vanishing
sigmoid函数 s i g m o i d ( x ) 1 1 exp ( − x ) sigmoid(x)\frac{1}{1 \exp(-x)} sigmoid(x)1exp(−x)1是导致梯度消失问题的一个常见的原因。
import matplotlib.pyplot as plt
import torch
from d2l import torch as d2l#梯度消失
x torch.arange(-8.0, 8.0, 0.1, requires_gradTrue)
y torch.sigmoid(x)
y.backward(torch.ones_like(x))d2l.plot(x.detach().numpy(), [y.detach().numpy(), x.grad.numpy()],legend[sigmoid, gradient], figsize(4.5, 2.5))
plt.show()如上图所示当sigmoid函数的输入很大或是很小时它的梯度都会消失。此外当反向传播通过许多层时除非sigmoid函数的输入都刚刚好接近于零否则整个乘积的梯度可能会消失。因此更稳定的ReLU系列函数已经成为默认选择。
4.8.1.2 Gradient Exploding
M torch.normal(0, 1, size(4,4))
print(一个矩阵 \n,M)
for i in range(100):M torch.mm(M,torch.normal(0, 1, size(4, 4)))print(乘以100个矩阵后\n, M)结果
一个矩阵
tensor([[-0.4430, 1.8467, 1.2274, 0.2537],[ 1.6749, -1.5996, 0.6402, 0.1141],[-0.1859, -0.4506, 2.5819, -1.3329],[ 2.7346, 0.1642, -0.6078, -0.0507]])
乘以100个矩阵后
tensor([[ 6.9875e23, 5.5570e23, 7.6843e23, -1.9781e23],[-6.3054e23, -5.0146e23, -6.9342e23, 1.7850e23],[ 6.4354e23, 5.1180e23, 7.0772e23, -1.8218e23],[-1.1732e24, -9.3301e23, -1.2902e24, 3.3212e23]])4.8.1.3 Symmetry
另一个问题是参数化所固有的对称性。假设我们有一个简单的多层感知机它有一个隐藏层和两个隐藏单元。在这种情况下我们可以对第一层的权重 W ( 1 ) \mathbf{W}^{(1)} W(1)进行重排列并且同样对输出层的权重进行重排列可以获得相同的函数。第一个隐藏单元与第二个隐藏单元没有什么特别的区别。换句话说我们在每一层的隐藏单元之间具有排列对称性。
假设输出层将上述两个隐藏单元的多层感知机转换为仅一个输出单元。如果我们将隐藏层的所有参数初始化为 W ( 1 ) c \mathbf{W}^{(1)} c W(1)c c c c为常量在前向传播期间两个隐藏单元采用相同的输入和参数产生相同的激活该激活被送到输出单元。在反向传播期间根据参数 W ( 1 ) \mathbf{W}^{(1)} W(1)对输出单元进行微分得到一个梯度其元素都取相同的值。因此在基于梯度的迭代例如小批量随机梯度下降之后 W ( 1 ) \mathbf{W}^{(1)} W(1)的所有元素仍然采用相同的值。这样的迭代永远不会打破对称性隐藏层的行为就好像只有一个单元我们可能永远也无法实现网络的表达能力。虽然小批量随机梯度下降不会打破这种对称性但暂退法正则化可以。
4.8.2 Xavier Initialization
解决或至少减轻上述问题的一种方法是进行参数初始化如果我们不指定初始化方法框架将使用默认的随机初始化方法。 现在深度学习中标准且实用的还有Xavier初始化。让我们看看某些没有非线性的全连接层输出例如隐藏变量 o i o_{i} oi的尺度分布。对于该层 n i n n_\mathrm{in} nin输入 x j x_j xj及其相关权重 w i j w_{ij} wij输出由下式给出 o i ∑ j 1 n i n w i j x j . o_{i} \sum_{j1}^{n_\mathrm{in}} w_{ij} x_j. oij1∑ninwijxj.
权重 w i j w_{ij} wij都是从同一分布中独立抽取的。此外让我们假设该分布具有零均值和方差 σ 2 \sigma^2 σ2这并不意味着分布必须是高斯的只是均值和方差需要存在。 让我们假设层 x j x_j xj的输入也具有零均值和方差 γ 2 \gamma^2 γ2并且它们独立于 w i j w_{ij} wij并且彼此独立在这种情况下我们可以按如下方式计算 o i o_i oi的平均值和方差 E [ o i ] ∑ j 1 n i n E [ w i j x j ] ∑ j 1 n i n E [ w i j ] E [ x j ] 0 , V a r [ o i ] E [ o i 2 ] − ( E [ o i ] ) 2 ∑ j 1 n i n E [ w i j 2 x j 2 ] − 0 ∑ j 1 n i n E [ w i j 2 ] E [ x j 2 ] n i n σ 2 γ 2 . \begin{aligned} E[o_i] \sum_{j1}^{n_\mathrm{in}} E[w_{ij} x_j] \\ \sum_{j1}^{n_\mathrm{in}} E[w_{ij}] E[x_j] \\ 0, \\ \mathrm{Var}[o_i] E[o_i^2] - (E[o_i])^2 \\ \sum_{j1}^{n_\mathrm{in}} E[w^2_{ij} x^2_j] - 0 \\ \sum_{j1}^{n_\mathrm{in}} E[w^2_{ij}] E[x^2_j] \\ n_\mathrm{in} \sigma^2 \gamma^2. \end{aligned} E[oi]Var[oi]j1∑ninE[wijxj]j1∑ninE[wij]E[xj]0,E[oi2]−(E[oi])2j1∑ninE[wij2xj2]−0j1∑ninE[wij2]E[xj2]ninσ2γ2.
保持方差不变的一种方法是设置 n i n σ 2 1 n_\mathrm{in} \sigma^2 1 ninσ21。 现在考虑反向传播过程我们面临着类似的问题。使用与前向传播相同的推断我们可以看到除非 n o u t σ 2 1 n_\mathrm{out} \sigma^2 1 noutσ21否则梯度的方差可能会增大其中 n o u t n_\mathrm{out} nout是该层的输出的数量。但我们不可能同时满足这两个条件因此我们只需满足 1 2 ( n i n n o u t ) σ 2 1 or σ 2 n i n n o u t . \begin{aligned} \frac{1}{2} (n_\mathrm{in} n_\mathrm{out}) \sigma^2 1 \text{ or } \sigma \sqrt{\frac{2}{n_\mathrm{in} n_\mathrm{out}}}. \end{aligned} 21(ninnout)σ21 or σninnout2 .
通常Xavier初始化从均值为零方差 σ 2 2 n i n n o u t \sigma^2 \frac{2}{n_\mathrm{in} n_\mathrm{out}} σ2ninnout2的高斯分布中采样权重。也可以利用Xavier的直觉来选择从均匀分布中抽取权重时的方差(注意均匀分布 U ( − a , a ) U(-a, a) U(−a,a)的方差为 a 2 3 \frac{a^2}{3} 3a2)将 a 2 3 \frac{a^2}{3} 3a2代入到 σ 2 \sigma^2 σ2的条件中将得到初始化域 U ( − 6 n i n n o u t , 6 n i n n o u t ) . U\left(-\sqrt{\frac{6}{n_\mathrm{in} n_\mathrm{out}}}, \sqrt{\frac{6}{n_\mathrm{in} n_\mathrm{out}}}\right). U(−ninnout6 ,ninnout6 ).
尽管在上述数学推理中“不存在非线性”的假设在神经网络中很容易被违反但Xavier初始化方法在实践中被证明是有效的。