当前位置: 首页 > news >正文

基于PyTorch的深度学习基础课程之十一:优化器

本文讨论了经典梯度下降法之外的常用优化器,它们都是基于梯度下降法进行了改进的方法,它们往往会比经典梯度下降法取得更好的优化速度和精度。掌握这些优化器的用法,并取得初步实践经验是提高深度学习应用能力的重要内容。读者在学习了基本知识后,要求AI大模型来辅助设置参数,提高效率。本文最后还简要说明了梯度消散和梯度爆炸问题。

本专栏之四讨论了梯度下降法,它是优化机器学习模型参数的基本方法。以它为基础,人们又发展出了许多改进方法,它们有不同的特点和适用场景。了解并实践这些内容,有助于选择合适的优化器及其参数以加快优化速度和精度。本文数学公式较多,读者也可以先跳过理论推导,通过示例掌握应用方法。

以梯度下降法为基础的改进方法,主要是从增加动量和调整步长两方面着手。

1.动量优化算法

在经典力学中,动量(Momentum)表示为物体的质量和速度的乘积,体现为物体运动的惯性。在梯度下降法(见本专栏之四)中,如果使梯度下降的过程具有一定的“动量”,保持原方向运动的一定的 “惯性”,则有可能在下降的过程中“冲过”小的“洼地”,避免陷入极小值点,如图11-1所示。其中,在第3个点处,其梯度负方向为蓝色虚线实箭头所示,而在动量的影响下,仍然保持向左的惯性,从而“冲出”了局部极小点。

图11-1 加入动量的梯度下降过程示意

加入动量优化,梯度下降法还可以克服前进路线振荡的问题,从而加快收敛速度。

梯度下降的迭代关系式(本专栏之四中的式4-1)为:
xi+1=xi+α⋅(−df(x)dx)x=xi=xi−α⋅df(x)dx∣x=xi x_{i+1} = x_i + \alpha \cdot \left( -\frac{df(x)}{dx} \right)_{x=x_i} = x_i - \alpha \cdot \frac{df(x)}{dx} \bigg|_{x=x_i}xi+1​=xi​+α⋅(−dxdf(x)​)x=xi​​=xi​−α⋅dxdf(x)​​x=xi​​
对照上式,加入动量的梯度下降法迭代关系式为:
θi+1=βθi−α⋅df(x)dx∣x=xixi+1=xi+θi+1(式11-1) \theta_{i+1} = \beta \theta_i - \alpha \cdot \left. \dfrac{df(x)}{dx} \right|_{x=x_i} \\[10pt] x_{i+1} = x_i + \theta_{i+1} \tag{式11-1}θi+1​=βθi​−α⋅dxdf(x)​​x=xi​​xi+1​=xi​+θi+1​(式11-1)
可见,加入动量之后的前进量θi+1\theta_{i+1}θi+1​是由上一步的前进量θi\theta_iθi​和新梯度值df(x)dx∣x=xi\frac{df(x)}{dx}\big|_{x=x_i}dxdf(x)​​x=xi​​的加权和,其中β\betaβ决定了保留上一步前进量的大小,称为动量系数。初始θ0=0\theta_0 = 0θ0​=0。

加入动量的梯度下降的迭代关系式还有一种改进方法,称为 NAG(Nesterov accelerated gradient):

θi+1=βθi−α⋅(df(x)dx)x=xi+βθixi+1=xi+θi+1(式11-2) \theta_{i+1} = \beta\theta_i - \alpha \cdot \left( \frac{df(x)}{dx} \right)_{x=x_i+\beta\theta_i}\\[10pt] x_{i+1} = x_i + \theta_{i+1}\tag{式11-2}θi+1​=βθi​−α⋅(dxdf(x)​)x=xi​+βθi​​xi+1​=xi​+θi+1​(式11-2)

该方法计算梯度的点发生了变化,即在xi+βθix_i + \beta\theta_ixi​+βθi​处计算梯度,而不是原xix_ixi​点处。它可以理解为先按“惯性”前进一小步βθi\beta\theta_iβθi​,再计算梯度。这种方法在每一步都往前多走了一小步,有时可以加快收敛速度。

在 PyTorch 中,动量优化和 NAG 方法主要通过设置torch.optim.SGD的momentum(动量系数)和nesterov两个参数的来实现。

代码11-1.1示例了它们的用法。

代码11-1.1 动量优化算法应用示例

### 1.导入和设置环境importtorchimporttorch.nnasnnimporttorch.optimasoptimfromtorch.utils.dataimportDataLoader,TensorDatasetimportdatetimefromtorchvisionimportdatasets,transforms# 设置随机种子torch.manual_seed(0)### 2.训练样本和验证样本数据预处理# 数据预处理方式transform=transforms.Compose([transforms.ToTensor(),# 转换为 torch.Tensor])# 加载MNIST数据集train_dataset=datasets.MNIST('./data',train=True,download=True,transform=transform)val_dataset=datasets.MNIST('./data',train=False,transform=transform)# 样本拉平、归一化后X_train=train_dataset.data.float().view(-1,784)/255.0y_train=train_dataset.targets X_val=val_dataset.data.float().view(-1,784)/255.0y_val=val_dataset.targets# 转换为独热编码y_train=torch.nn.functional.one_hot(y_train,num_classes=10).float()y_val=torch.nn.functional.one_hot(y_val,num_classes=10).float()# 创建数据加载器batch_size=200train_loader=DataLoader(TensorDataset(X_train,y_train),batch_size=batch_size,shuffle=True)val_loader=DataLoader(TensorDataset(X_val,y_val),batch_size=batch_size)### 3.定义神经网络模型# relu-relu-softmaxclassMNISTModel(nn.Module):def__init__(self):super(MNISTModel,self).__init__()self.fc1=nn.Linear(784,784)self.fc2=nn.Linear(784,784)self.fc3=nn.Linear(784,10)self.relu=nn.ReLU()self.softmax=nn.Softmax()defforward(self,x):x=self.relu(self.fc1(x))x=self.relu(self.fc2(x))x=self.softmax(self.fc3(x))returnx### 4.采用不同的优化器进行对比试验deftrain_process():# 训练模型,开始计时start_time=datetime.datetime.now()epochs=10forepochinrange(epochs):# 每轮中的训练model.train()train_loss=0.0forbatch_X,batch_yintrain_loader:optimizer.zero_grad()outputs=model(batch_X)loss=criterion(outputs,batch_y)loss.backward()optimizer.step()train_loss+=loss.item()# 看一下该轮训练后的效果model.eval()correct=0total=0withtorch.no_grad():forbatch_X,batch_yintrain_loader:outputs=model(batch_X)_,predicted=torch.max(outputs.data,1)# 模型预测值的独热编码_,labels=torch.max(batch_y.data,1)# 真实标签值的独热编码total+=labels.size(0)correct+=(predicted==labels).sum().item()# 准确率print(f'Epoch{epoch+1}/{epochs}, 对训练样本进行预测的准确率(Train Acc):{100*correct/total:.2f}%')# 训练结束,终止计时end_time=datetime.datetime.now()print(f"训练用时:{end_time-start_time}")criterion=nn.MSELoss()model=MNISTModel()optimizer=optim.SGD(model.parameters(),lr=0.15)# 基本梯度下降法优化器train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 46.40%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 42.39%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 51.85%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 58.24%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 74.46%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 82.62%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 85.90%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 87.47%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 88.53%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 89.14%
训练用时: 0:01:19.254175

criterion=nn.MSELoss()model=MNISTModel()optimizer=optim.SGD(model.parameters(),lr=0.15,momentum=0.9)# 启用动量优化的梯度下降法优化器train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 88.11%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 91.55%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 92.71%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 93.86%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 94.56%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 95.15%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 95.60%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 95.87%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 96.29%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 96.86%
训练用时: 0:01:25.797210

criterion=nn.MSELoss()model=MNISTModel()optimizer=optim.SGD(model.parameters(),lr=0.15,momentum=0.9,nesterov=True)# 启用NAG的梯度下降法优化器train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 87.90%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 91.56%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 92.46%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 93.72%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 94.41%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 95.05%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 95.57%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 96.07%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 96.58%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 96.87%
训练用时: 0:01:24.306429

2.步长优化算法

在讨论梯度下降法时,简要说明了步长对梯度下降的影响。针对步长,人们研究了不少的优化算法。

2.1 Adagrad算法

Adagrad(Adaptive Gradient)算法的梯度迭代关系式为:

ri=ri−1+(df(x)dx∣x=xi)2xi=xi−1−lrri+ϵ⋅df(x)dx∣x=xi(式11-3) r_i = r_{i-1} + \left(\frac{df(\boldsymbol{x})}{d\boldsymbol{x}}\bigg|_{\boldsymbol{x}=\boldsymbol{x}_i}\right)^2 \\ x_i = x_{i-1} - \frac{lr}{\sqrt{r_i + \epsilon}} \cdot \frac{df(x)}{dx}\bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \tag{式11-3}ri​=ri−1​+(dxdf(x)​​x=xi​​)2xi​=xi−1​−ri​+ϵ​lr​⋅dxdf(x)​​x=xi​​(式11-3)

其中,rir_iri​称为累积平方梯度,它是到当前为止所有梯度的平方和,初值为000。这里的(df(x)dx∣x=xi)x=xi2\left( \frac{df(x)}{dx}\bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \right)_{x=x_i}^2(dxdf(x)​​x=xi​​)x=xi​2​表示向量元素的平方向量:df(x)dx∣x=xi⨀df(x)dx∣x=xi\frac{df(x)}{dx} \bigg|_{x=x_i} \bigodot \frac{df(x)}{dx} \bigg|_{x=x_i}dxdf(x)​​x=xi​​⨀dxdf(x)​​x=xi​​,下同。超参数lrlrlr为事先设置的步长,ϵ\epsilonϵ为很小的常数。初始r0=0r_0 = 0r0​=0。

可见,随着迭代次数的增加,rir_iri​越来越大,实际步长lrri+1+ϵ\frac{lr}{\sqrt{r_{i+1}}+\epsilon}ri+1​​+ϵlr​越来越小,可以防止在极小值附近来回振荡。

PyTorch中实现该算法的是torch.optim.Adagrad(),它的lr、eps和initial_accumulator_value三个参数分别设置lrlrlr、ϵ\epsilonϵ和r0r_0r0​,另外还设置了步长衰减参数lr_decay和L2正则化参数weight_decay。

该算法的应用示例如代码11-1.2所示。

代码11-1.2 Adagrad优化器应用示例

criterion=nn.MSELoss()model=MNISTModel()optimizer=optim.Adagrad(model.parameters(),lr=0.01)# Adagrad优化器train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 96.76%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 98.04%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 98.64%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 98.97%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 99.20%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 99.36%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 99.51%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 99.58%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 99.64%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 99.70%
训练用时: 0:01:19.308178

2.2 RMSProp算法

RMSProp(Root Mean Square Prop)算法的原始形式对Adagrad算法进行了简单改进,增加了一个系数rhorhorho来控制历史信息与当前梯度的比例:

ri=rho⋅ri−1+(1−rho)(df(x)dx∣x=xi)2xi=xi−1−lrri+ϵ⋅df(x)dx∣x=xi(式11-4) r_i = rho \cdot r_{i-1} + (1 - rho) \left( \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \right)^2 \\ \boldsymbol{x}_i = \boldsymbol{x}_{i-1} - \frac{lr}{\sqrt{r_i + \epsilon}} \cdot \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \tag{式11-4}ri​=rho⋅ri−1​+(1−rho)(dxdf(x)​​x=xi​​)2xi​=xi−1​−ri​+ϵ​lr​⋅dxdf(x)​​x=xi​​(式11-4)

对RMSProp的原始形式增加动量因子如下:

ri=rho⋅ri−1+(1−rho)(df(x)dx∣x=xi)2θi=βθi−1+lrri+ϵ⋅df(x)dx∣x=xixi=xi−1−θi(式11-5) r_i = rho \cdot r_{i-1} + (1 - rho) \left( \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \right)^2 \\ \boldsymbol{\theta}_i = \beta \boldsymbol{\theta}_{i-1} + \frac{lr}{\sqrt{r_i + \epsilon}} \cdot \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \\ \boldsymbol{x}_i = \boldsymbol{x}_{i-1} - \boldsymbol{\theta}_i \tag{式11-5}ri​=rho⋅ri−1​+(1−rho)(dxdf(x)​​x=xi​​)2θi​=βθi−1​+ri​+ϵ​lr​⋅dxdf(x)​​x=xi​​xi​=xi−1​−θi​(式11-5)

其中,β\betaβ为动量系数。

下式为 RMSProp 的中心化版本:

si=rho⋅si−1+(1−rho)df(x)dx∣x=xiri=rho⋅ri−1+(1−rho)(df(x)dx∣x=xi)2θi=βθi−1+lrri−si2+ϵ⋅df(x)dx∣x=xixi=xi−1−θi(式11-6) \boldsymbol{s}_i = rho \cdot \boldsymbol{s}_{i-1} + (1 - rho) \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \\ r_i = rho \cdot r_{i-1} + (1 - rho) \left( \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \right)^2\\ \boldsymbol{\theta}_i = \beta \boldsymbol{\theta}_{i-1} + \frac{lr}{\sqrt{r_i - \boldsymbol{s}_i^2 + \epsilon}} \cdot \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i}\\ \boldsymbol{x}_i = \boldsymbol{x}_{i-1} - \boldsymbol{\theta}_i\tag{式11-6}si​=rho⋅si−1​+(1−rho)dxdf(x)​​x=xi​​ri​=rho⋅ri−1​+(1−rho)(dxdf(x)​​x=xi​​)2θi​=βθi−1​+ri​−si2​+ϵ​lr​⋅dxdf(x)​​x=xi​​xi​=xi−1​−θi​(式11-6)

它增加了一个累积梯度si\boldsymbol{s}_isi​,在求动量因子θi\boldsymbol{\theta}_iθi​时,通过si\boldsymbol{s}_isi​对rir_iri​进行了一个中心化过程:ri−si2初始s0=0,r0=0r_i - \boldsymbol{s}_i^2 \quad 初始 \boldsymbol{s}_0 = \boldsymbol{0}, r_0 = 0ri​−si2​初始s0​=0,r0​=0。

RMSProp 在实践中效果较好,得到了较多的应用,在 PyTorch中也提供了实现类,可以通过设置相关参数来实现以上三个版本的 RMSProp 算法。

该算法的应用示例如代码11-1.3所示。

代码11-1.3 RMSProp 优化器应用示例

criterion=nn.MSELoss()model=MNISTModel()optimizer=torch.optim.RMSprop(model.parameters(),lr=0.001,momentum=0,centered=False)# RMSprop优化器原始版本train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 95.33%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 98.02%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 98.21%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 98.82%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 98.91%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 99.33%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 99.35%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 99.36%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 99.36%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 99.54%
训练用时: 0:02:55.587366

criterion=nn.MSELoss()model=MNISTModel()optimizer=torch.optim.RMSprop(model.parameters(),lr=0.001,alpha=0.9,# 梯度平滑系数momentum=0.8,# 添加动量加速收敛weight_decay=1e-5,# L2正则化centered=False)train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 93.75%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 96.19%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 95.52%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 97.39%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 97.03%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 97.13%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 97.80%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 97.58%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 97.05%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 97.30%
训练用时: 0:07:34.488462

criterion=nn.MSELoss()model=MNISTModel()optimizer=torch.optim.RMSprop(model.parameters(),lr=0.001,alpha=0.9,# 梯度平滑系数momentum=0.8,# 添加动量加速收敛weight_decay=1e-5,# L2正则化centered=True# 中心化)train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 91.83%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 95.06%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 96.34%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 95.43%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 96.05%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 97.22%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 97.39%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 97.39%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 97.46%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 96.95%
训练用时: 0:06:58.417171

3.结合动量和步长优化的算法

Adam(Adaptive moment estimation)算法结合了AdaGrad算法和RMSProp算法的优势,它的迭代关系式为:
si=β1⋅si−1+(1−β1)df(x)dx∣x=xiri=β2⋅ri−1+(1−β2)(df(x)dx∣x=xi)2s^i=si1−β1ir^i=ri1−β2ixi=xi−1−lr⋅s^ir^i+ϵ(式11-7) \boldsymbol{s}_i = \beta_1 \cdot \boldsymbol{s}_{i-1} + (1 - \beta_1) \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i}\\ r_i = \beta_2 \cdot r_{i-1} + (1 - \beta_2) \left( \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \right)^2\\ \hat{\boldsymbol{s}}_i = \frac{\boldsymbol{s}_i}{1 - \beta_1^i}\\ \hat{r}_i = \frac{r_i}{1 - \beta_2^i}\\ \boldsymbol{x}_i = \boldsymbol{x}_{i-1} - \frac{lr \cdot \hat{\boldsymbol{s}}_i}{\sqrt{\hat{r}_i} + \epsilon}\tag{式11-7}si​=β1​⋅si−1​+(1−β1​)dxdf(x)​​x=xi​​ri​=β2​⋅ri−1​+(1−β2​)(dxdf(x)​​x=xi​​)2s^i​=1−β1i​si​​r^i​=1−β2i​ri​​xi​=xi−1​−r^i​​+ϵlr⋅s^i​​(式11-7)

式中,β1,β2∈[0,1]\beta_1, \beta_2 \in [0, 1]β1​,β2​∈[0,1]分别为累积梯度的动量系数和累积平方梯度的动量系数。初始s0=0,r0=0\boldsymbol{s}_0 = \boldsymbol{0}, r_0 = 0s0​=0,r0​=0。

对比式11-7和式11-6,可知Adam算法是RMSProp中心化版本的进一步改进。

对累积平方梯度rir_iri​可以取历史最大值用来更新,称为 AMSGrad,此时 Adam 算法为:

si=β1⋅si−1+(1−β1)df(x)dx∣x=xiri=β2⋅ri−1+(1−β2)(df(x)dx∣x=xi)2ri′=max⁡(ri−1′,ri)s^i=si1−β1ir^i=ri′1−β2ixi=xi−1−lr⋅s^ir^i+ϵ(式11-8) \boldsymbol{s}_i = \beta_1 \cdot \boldsymbol{s}_{i-1} + (1 - \beta_1) \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i}\\ r_i = \beta_2 \cdot r_{i-1} + (1 - \beta_2) \left( \frac{df(\boldsymbol{x})}{d\boldsymbol{x}} \bigg|_{\boldsymbol{x}=\boldsymbol{x}_i} \right)^2\\ r_i' = \max(r_{i-1}', r_i)\\ \hat{\boldsymbol{s}}_i = \frac{\boldsymbol{s}_i}{1 - \beta_1^i}\\ \hat{r}_i = \frac{r_i'}{1 - \beta_2^i}\\ \boldsymbol{x}_i = \boldsymbol{x}_{i-1} - \frac{lr \cdot \hat{\boldsymbol{s}}_i}{\sqrt{\hat{r}_i} + \epsilon}\tag{式11-8}si​=β1​⋅si−1​+(1−β1​)dxdf(x)​​x=xi​​ri​=β2​⋅ri−1​+(1−β2​)(dxdf(x)​​x=xi​​)2ri′​=max(ri−1′​,ri​)s^i​=1−β1i​si​​r^i​=1−β2i​ri′​​xi​=xi−1​−r^i​​+ϵlr⋅s^i​​(式11-8)

初始r0′=0r_0' = 0r0′​=0。

Adam 算法综合效果较好,在PyTorch 中有相应的实现类,通过设置参数可以实现上述两个算法。

该算法的应用示例如代码11-1.4所示。

代码11-1.4 Adam 优化器应用示例

criterion=nn.MSELoss()model=MNISTModel()optimizer=optim.Adam(model.parameters(),lr=0.001)# Adam优化器train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 95.18%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 97.85%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 98.42%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 98.30%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 99.01%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 99.27%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 99.30%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 98.91%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 99.43%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 99.30%
训练用时: 0:01:35.730784

criterion=nn.MSELoss()model=MNISTModel()optimizer=optim.Adam(model.parameters(),lr=0.001,amsgrad=True)# Adam优化器AMSGrad版本train_process()

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 96.44%
Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 97.58%
Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 98.43%
Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 98.59%
Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 98.85%
Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 99.06%
Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 99.37%
Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 99.42%
Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 99.42%
Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 99.56%
训练用时: 0:01:41.566383

不同的优化算法有不同的特点,读者可通过更多的练习来摸索它们的应用方法和特点。

4.梯度消散与梯度爆炸问题

本专栏中,本文之前的几篇文章讨论了多层神经网络的激活函数、损失函数和优化器等问题。这里简要说明一下与这几个问题都有关的在多层神经网络训练中非常重要的梯度消散和梯度爆炸问题。

在校对误差反向传播的过程中,如果偏导数较小,在多次连乘之后,校对误差会趋近于0,导致梯度也趋近于0,前面层的参数无法得到有效更新,称之为梯度消散。梯度消散会使得增加再多的层也无法提高效果,甚至反而会降低。

相反,如果偏导数较大,则会在反向传播的过程中呈指数级增长,导致溢出,无法计算,网络不稳定,称之为梯度爆炸。

梯度消散和梯度爆炸只在层次较多的网络中出现,常用的解决方法包括尽量使用合适的激活函数(如Relu函数,它在正数部分导数为1)和损失函数;适当的优化器;预训练;合适的网络模型(有些网络模型具有防消散和爆炸能力,将在后文讨论);梯度截断等等。

http://www.cnnetsun.cn/news/69403.html

相关文章:

  • HUB扩展:数字世界的隐形枢纽与生态重构者
  • 基于能量分配的光伏混合储能系统仿真模型:MPPT控制光伏最大功率跟踪,电池与超级电容协同工作实...
  • 【WebSocket稳定性提升秘诀】:如何在生产环境中规避7类典型错误
  • 为什么你的协程系统响应迟缓?优先级调度设计缺陷可能是罪魁祸首
  • 构造函数返回对象时的陷阱:为什么 `return {}` 会覆盖 new 操作符的默认行为
  • 宏任务与微任务的边界:为什么在不同浏览器环境下 Promise 的执行时序可能不一致
  • 智能工牌如何帮房企智能盘客,提升销售转化?
  • LP3713CH_5W/SOP7隔离适配器和充电器自供电PSR控制芯片 典型应用电路
  • FT8393MB1(5V/2.4A)12W线式电源控制芯片 典型应用电路
  • [吾爱大神原创工具] Python脚本打包为“EXE”工具(史上最高颜值)
  • 当电机遇上滑移:四轮驱动车能耗与稳定性的双线作战
  • AI视频工具普及,为何内容团队工时反增20%?
  • SQL多表查询实战:7种JOIN详解
  • 变量传递总是出错?掌握这3个核心原理,轻松打通R与Python壁垒
  • jmeter基础使用方法
  • 直接打开MATLAB,先来点刺激的——搞个巴特沃斯低通滤波器。别被名字吓到,其实就是个能让低频信号通过,高频滚犊子的电路模型。看这段
  • 大模型应用开发核心:构建高效准确的提示词指南
  • OpenAI发布GPT-5.2:是王者归来还是强弩之末?
  • HTTPS DDoS 排查 异常流量到抓包分析
  • 12、Docker与Kubernetes使用指南
  • 行为树优化全攻略(性能翻倍的4个秘密武器)
  • 直流电机双闭环调速系统仿真模型:转速外环与电流内环PI参数整定指南,无静差跟踪实现功能介绍
  • 滑膜控制下的差动制动防侧翻稳定系统设计与仿真验证:横摆力矩分配策略及其实车测试分析
  • 模型压缩技术详解:剪枝、量化与知识蒸馏,让你的大模型轻量化部署
  • Iridescent:Day23
  • Laravel 13多模态权限实现技巧(99%的开发者忽略的关键细节)
  • 测试数据自动生成方法:策略、实施与最佳实践
  • 【医疗数据安全防线】:如何用PHP构建自动备份体系
  • 【R-Python模型融合实战】:揭秘跨平台建模结果验证的5大核心步骤
  • 从田间到R控制台,方差分析如何改变传统农业决策?