从0开始深度学习(17)——数值稳定性和模型初始化

在每次训练之前,都会对模型的参数进行初始化,初始化方案的选择在神经网络学习中起着举足轻重的作用, 它对保持数值稳定性至关重要。

我们选择哪个函数以及如何初始化参数 可以决定优化算法收敛的速度有多快。 糟糕选择可能会导致我们在训练时遇到梯度爆炸梯度消失

1 梯度消失和梯度爆炸

不稳定梯度带来的风险不止在于数值表示; 不稳定梯度也威胁到我们优化算法的稳定性。 我们可能面临一些问题:

要么是**梯度爆炸(gradient exploding)问题: 参数更新过大,破坏了模型的稳定收敛;
要么是
梯度消失(gradient vanishing)**问题: 参数更新过小,在每次更新时几乎不会移动,导致模型无法学习。

1.1 梯度消失

这里以sigmoid函数为例,因为它类似于阈值函数,所以也容易导致梯度消失,我们创建了一个从 -8.0 到 8.0,步长为 0.1 的一维张量 x,使用sigmoid函数,然后计算 y 对 x 的梯度,最后输出一个横轴是x,y轴是梯度的图像

python 复制代码
%matplotlib inline
import torch
from d2l import torch as d2l

x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
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))

我们发现,当sigmoid函数的输入很大或是很小时,它的梯度都会消失,所以一旦某个网络层的输入过大或者过小,梯度就会消失, 因此,更稳定的ReLU系列函数称为了默认选择

1.2 梯度爆炸

通过构造一个简单的递归函数或链式乘法,可以看到梯度在反向传播过程中如何逐渐增大

python 复制代码
%matplotlib inline
import torch
from d2l import torch as d2l

# 构造从 -1 到 1 的输入数据,并启用梯度计算
x = torch.tensor(1.0, requires_grad=True)

# 模拟梯度爆炸:我们构造一个由 100 个常数值相乘的过程
y = x
for i in range(100):  # 重复 100 次
    y = y * 1.1  # 每次乘以 1.1

# 反向传播
y.backward()

# 绘制结果
x_grad = x.grad.item()
print(f"x 的梯度值为: {x_grad}")

# 由于我们反复放大,梯度会呈指数增长,这就是梯度爆炸的表现。

当这种情况是由于深度网络的初始化所导致时,我们没有机会让梯度下降优化器收敛。

1.3 对称性问题

如果所有的神经元(同一层中的神经元)具有相同的初始权重,它们将学到相同的特征。这种现象会让网络的学习过程失去多样性,进而影响模型的表达能力和训练效果。

例如,如果你把每一层的所有神经元的权重都初始化为 0 或相同的值,网络中的每个神经元都会执行相同的计算,这样就失去了通过不同神经元学习不同特征的意义。

1.4 打破对称性

打破对称性就是在网络初始化时,为每个神经元赋予不同的初始权重值,确保它们在训练过程中能学习到不同的特征。通常的做法是随机初始化权重 ,同样的还能使用暂退法正则化来打破

2 参数初始化

解决(或至少减轻)上述问题的一种方法是进行参数初始化

2.1 默认初始化

之前的例子中,我们一直使用的是正态分布来初始化权重,如果不指定,pytorch框架会使用默认的随机初始化方法。

2.2 Xavier初始化( Glorot 初始化)

核心思想:

Xavier 初始化的目标是确保信号的方差在每一层传播时保持一致,即:

  • 前向传播中,输出的激活值的方差保持稳定,避免过大或过小。
  • 反向传播中,梯度的方差同样保持稳定,避免梯度爆炸或梯度消失。

为了实现这个目标,Xavier 初始化根据输入和输出层的神经元数量,计算合适的初始权重分布。具体公式如下:

对于权重矩阵中的每个元素 W i j W_{ij} Wij ,其初始化值从一个均匀分布或正态分布中随机采样:

  1. 均匀分布:
  1. 正态分布:

​其中:

  • n i n n_{in} nin是该层神经元的输入节点数量(上一层的神经元数量)。
  • n o u t n_{out} nout是该层神经元的输出节点数量(下一层的神经元数量)。

PyTorch 中提供了 Xavier 初始化的方法,可以直接使用 torch.nn.init.xavier_uniform_ 或 torch.nn.init.xavier_normal_ 来应用 Xavier 初始化。

python 复制代码
import torch
import torch.nn as nn

linear = nn.Linear(100, 50)  
# 使用 Xavier 均匀初始化
nn.init.xavier_uniform_(linear.weight)
# 如果需要 Xavier 正态分布初始化
# nn.init.xavier_normal_(linear.weight)

Xavier 初始化通过平衡前向和反向传播中信号和梯度的方差,能够有效地帮助深层网络稳定训练,特别是对于使用 sigmoid 或 tanh 激活函数的网络非常重要。

相关推荐
阿坡RPA12 小时前
手搓MCP客户端&服务端:从零到实战极速了解MCP是什么?
人工智能·aigc
用户277844910499312 小时前
借助DeepSeek智能生成测试用例:从提示词到Excel表格的全流程实践
人工智能·python
机器之心12 小时前
刚刚,DeepSeek公布推理时Scaling新论文,R2要来了?
人工智能
算AI14 小时前
人工智能+牙科:临床应用中的几个问题
人工智能·算法
凯子坚持 c15 小时前
基于飞桨框架3.0本地DeepSeek-R1蒸馏版部署实战
人工智能·paddlepaddle
你觉得20515 小时前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义下载方法
大数据·人工智能·python·gpt·学习·机器学习·aigc
8K超高清15 小时前
中国8K摄像机:科技赋能文化传承新图景
大数据·人工智能·科技·物联网·智能硬件
hyshhhh16 小时前
【算法岗面试题】深度学习中如何防止过拟合?
网络·人工智能·深度学习·神经网络·算法·计算机视觉
薛定谔的猫-菜鸟程序员16 小时前
零基础玩转深度神经网络大模型:从Hello World到AI炼金术-详解版(含:Conda 全面使用指南)
人工智能·神经网络·dnn
币之互联万物16 小时前
2025 AI智能数字农业研讨会在苏州启幕,科技助农与数据兴业成焦点
人工智能·科技