淘宝客网站可以备案吗,微建站平台,昆山网站建设有限公司怎么样,axrue怎么做网站的原型图文章目录 神经网络入门二3 神经网络优化方法3.1 梯度下降算法回顾3.2 反向传播#xff08;BP算法#xff09;3.2.1 反向传播概念3.2.2 反向传播详解 3.3 梯度下降优化方法3.3.1 指数加权平均3.3.2 动量算法Momentum3.3.3 AdaGrad3.3.4 RMSProp3.3.5 Adam3.3.6 小结 4 学习率衰… 文章目录 神经网络入门二3 神经网络优化方法3.1 梯度下降算法回顾3.2 反向传播BP算法3.2.1 反向传播概念3.2.2 反向传播详解 3.3 梯度下降优化方法3.3.1 指数加权平均3.3.2 动量算法Momentum3.3.3 AdaGrad3.3.4 RMSProp3.3.5 Adam3.3.6 小结 4 学习率衰减优化方法4.1 为什么要进行学习率优化4.2 等间隔学习率衰减4.3 指定间隔学习率衰减4.4 按指数学习率衰减4.5 小结 5 正则化方法5.1 什么是正则化5.2 Dropout正则化5.3 批量归一正则化(Batch Normalization) 神经网络入门二
3 神经网络优化方法
多层神经网络的学习能力比单层网络强得多。想要训练多层网络需要更强大的学习算法。误差反向传播算法Back Propagation是其中最杰出的代表它是目前最成功的神经网络学习算法。现实任务使用神经网络时大多是在使用 BP 算法进行训练值得指出的是 BP 算法不仅可用于多层前馈神经网络还可以用于其他类型的神经网络。通常说 BP 网络时一般是指用 BP 算法训练的多层前馈神经网络。
这就需要了解两个概念
正向传播指的是数据通过网络从输入层到输出层的传递过程。这个过程的目的是计算网络的输出值预测值从而与目标值真实值比较以计算误差。反向传播指的是计算损失函数相对于网络中各参数权重和偏置的梯度指导优化器更新参数从而使神经网络的预测更接近目标值。
3.1 梯度下降算法回顾
梯度下降法简单来说就是一种寻找使损失函数最小化的方法。
从数学角度来看梯度的方向是函数增长速度最快的方向那么梯度的反方向就是函数减少最快的方向所以有 其中η是学习率如果学习率太小那么每次训练之后得到的效果都太小增大训练的时间成本。如果学习率太大那就有可能直接跳过最优解进入无限的训练中。解决的方法就是学习率也需要随着训练的进行而变化。 在上图中我们展示了一维和多维的损失函数损失函数呈碗状。在训练过程中损失函数对权重的偏导数就是损失函数在该位置点的梯度。我们可以看到沿着负梯度方向移动就可以到达损失函数底部从而使损失函数最小化。这种利用损失函数的梯度迭代地寻找最小值的过程就是梯度下降的过程。
在进行模型训练时有三个基础的概念
Epoch: 使用全部数据对模型进行以此完整训练训练次数Batch: 使用训练集中的小部分样本对模型权重进行以此反向传播的参数更新每次训练每批次样本数量Iteration: 使用一个 Batch 数据对模型进行一次参数更新的过程每次训练批次数
假设数据集有 50000 个训练样本现在选择 Batch Size 256 对模型进行训练。 每个 Epoch 要训练的图片数量50000 训练集具有的 Batch 个数50000/2561196 每个 Epoch 具有的 Iteration 个数196 10个 Epoch 具有的 Iteration 个数1960
在深度学习中梯度下降的几种方式的根本区别就在于Batch Size不同,如下表所示 注上表中 Mini-Batch 的 Batch 个数为 N / B 1 是针对未整除的情况。整除则是 N / B。
3.2 反向传播BP算法 利用反向传播算法对神经网络进行训练。该方法与梯度下降算法相结合对网络中所有权重计算损失函数的梯度并利用梯度值来更新权值以最小化损失函数。 3.2.1 反向传播概念
前向传播指的是数据输入到神经网络中逐层向前传输一直运算到输出层为止。
反向传播Back Propagation利用损失函数ERROR值从后往前结合梯度下降算法依次求各个参数的偏导并进行参数更新。 在网络的训练过程中经过前向传播后得到的最终结果跟训练样本的真实值总是存在一定误差这个误差便是损失函数 ERROR。想要减小这个误差就用损失函数 ERROR从后往前依次求各个参数的偏导这就是反向传播Back Propagation。
3.2.2 反向传播详解
反向传播算法利用链式法则对神经网络中的各个节点的权重进行更新。
【举个栗子】
如下图是一个简单的神经网络用来举例激活函数为sigmoid 前向传播运算 接下来是反向传播求网络误差对各个权重参数的梯度
我们先来求最简单的求误差E对w5的导数。首先明确这是一个链式法则的求导过程要求误差E对w5的导数需要先求误差E对 o u t o 1 out_{o1} outo1的导数再求 o u t o 1 out_{o1} outo1对 n e t o 1 net_{o1} neto1的导数最后再求 n e t o 1 net_{o1} neto1对 w 5 w_5 w5的导数经过这个链式法则我们就可以求出误差E对 w 5 w_5 w5的导数偏导如下图所示 导数梯度已经计算出来了下面就是反向传播与参数更新过程 如果要想求误差E对w1的导数误差E对w1的求导路径不止一条这会稍微复杂一点但换汤不换药计算过程如下所示 至此反向传播算法的过程就讲完了啦
3.3 梯度下降优化方法
梯度下降优化算法中可能会碰到以下情况
碰到平缓区域梯度值较小参数优化变慢碰到 “鞍点” 梯度为0参数无法优化碰到局部最小值参数不是最优
对于这些问题, 出现了一些对梯度下降算法的优化方法例如Momentum、AdaGrad、RMSprop、Adam 等 3.3.1 指数加权平均
我们最常见的算数平均指的是将所有数加起来除以数的个数每个数的权重是相同的。指数加权平均指的是给每个数赋予不同的权重求得平均数。移动平均数指的是计算最近邻的 N 个数来获得平均数。
指数移动加权平均则是参考各数值并且各数值的权重都不同距离越远的数字对平均数计算的贡献就越小权重较小距离越近则对平均数的计算贡献就越大权重越大。
比如明天气温怎么样和昨天气温有很大关系而和一个月前的气温关系就小一些。
计算公式可以用下面的式子来表示 S t S_t St 表示指数加权平均值; Y t Y_t Yt 表示t时刻的值;β 调节权重系数该值越大平均数越平缓。
第100天的指数加权平均值为: 下面通过代码来看结果随机产生 30 天的气温数据
import torch
import matplotlib.pyplot as pltELEMENT_NUMBER 30# 1. 实际平均温度
def test01():# 固定随机数种子torch.manual_seed(0)# 产生30天的随机温度temperature torch.randn(size[ELEMENT_NUMBER,]) * 10print(temperature)# 绘制平均温度days torch.arange(1, ELEMENT_NUMBER 1, 1)plt.plot(days, temperature, colorr)plt.scatter(days, temperature)plt.show()# 2. 指数加权平均温度
def test02(beta0.9):# 固定随机数种子torch.manual_seed(0)# 产生30天的随机温度temperature torch.randn(size[ELEMENT_NUMBER,]) * 10print(temperature)exp_weight_avg []# idx从1开始for idx, temp in enumerate(temperature, 1):# 第一个元素的 EWA 值等于自身if idx 1:exp_weight_avg.append(temp)continue# 第二个元素的 EWA 值等于上一个 EWA 乘以 β 当前气温乘以 (1-β)# idx-22-20exp_weight_avg列表中第一个值的下标值new_temp exp_weight_avg[idx - 2] * beta (1 - beta) * tempexp_weight_avg.append(new_temp)days torch.arange(1, ELEMENT_NUMBER 1, 1)plt.plot(days, exp_weight_avg, colorr)plt.scatter(days, temperature)plt.show()if __name__ __main__:test01()test02(0.5)test02(0.9)从程序运行结果可以看到
指数加权平均绘制出的气温变化曲线更加平缓β 的值越大则绘制出的折线越加平缓波动越小(1-β越小,t时刻的 S t S_t St越不依赖 Y t Y_t Yt的值)β 值一般默认都是 0.9
3.3.2 动量算法Momentum
当梯度下降碰到 “峡谷” 、”平缓”、”鞍点” 区域时, 参数更新速度变慢。 Momentum 通过指数加权平均法累计历史梯度值进行参数更新越近的梯度值对当前参数更新的重要性越大。
梯度计算公式
s t β s t − 1 ( 1 − β ) g t s_tβs_{t−1}(1−β)g_t stβst−1(1−β)gt
参数更新公式
w t w t − 1 − η s t w_tw_{t−1}−ηs_t wtwt−1−ηst s t s_t st是当前时刻指数加权平均梯度值 s t − 1 s_{t-1} st−1是历史指数加权平均梯度值 g t g_t gt是当前时刻的梯度值
β 是调节权重系数通常取 0.9 或 0.99
η是学习率 w t w_t wt是当前时刻模型权重参数
咱们举个例子假设权重 β 为 0.9例如
第一次梯度值s1 g1 w1
第二次梯度值s2 0.9*s1 g2*0.1
第三次梯度值s3 0.9*s2 g3*0.1
第四次梯度值s4 0.9*s3 g4*0.1
1. w 表示初始梯度
2. g 表示当前轮数计算出的梯度值
3. s 表示历史梯度移动加权平均值梯度下降公式中梯度的计算就不再是当前时刻t的梯度值而是历史梯度值的指数移动加权平均值。
公式修改为
Wt Wt-1 - η*St
Wt当前时刻模型权重参数
St当前时刻指数加权平均梯度值
η学习率Monmentum 优化方法是如何一定程度上克服 “平缓”、”鞍点”、”峡谷” 的问题呢 当处于鞍点位置时由于当前的梯度为 0参数无法更新。但是 Momentum 动量梯度下降算法已经在先前积累了一些梯度值很有可能使得跨过鞍点。由于 mini-batch 普通的梯度下降算法每次选取少数的样本梯度确定前进方向可能会出现震荡使得训练时间变长。Momentum 使用移动加权平均平滑了梯度的变化使得前进方向更加平缓有利于加快训练过程。一定程度上有利于降低 “峡谷” 问题的影响。
在pytorch中动量梯度优化法编程实践如下
def test01():# 1 初始化权重参数w torch.tensor([1.0], requires_gradTrue, dtypetorch.float32)loss ((w ** 2) / 2.0).sum()# 2 实例化优化方法SGD 指定参数beta0.9optimizer torch.optim.SGD([w], lr0.01, momentum0.9)# 3 第1次更新 计算梯度并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print(第1次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))# 4 第2次更新 计算梯度并对参数进行更新# 使用更新后的参数机选输出结果loss ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print(第2次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))结果显示
第1次: 梯度w.grad: 1.000000, 更新后的权重:0.990000
第2次: 梯度w.grad: 0.990000, 更新后的权重:0.9711003.3.3 AdaGrad
AdaGrad 通过对不同的参数分量使用不同的学习率AdaGrad 的学习率总体会逐渐减小这是因为 AdaGrad 认为在起初时我们距离最优目标仍较远可以使用较大的学习率加快训练速度随着迭代次数的增加学习率逐渐下降。
其计算步骤如下 初始化学习率 η、初始化参数w、小常数 σ 1e-10 初始化梯度累计变量 s 0 从训练集中采样 m 个样本的小批量计算梯度 g t g_t gt 累积平方梯度: s t s_t st s t − 1 s_{t-1} st−1 g t g_t gt ⊙ g t g_t gt⊙ 表示各个分量相乘 学习率 η 的计算公式如下 η η s t σ η\over\sqrt{s_t}σ st ση 权重参数更新公式如下 w t w_t wt w t − 1 w_{t-1} wt−1 - η s t σ η\over\sqrt{s_t}σ st ση * g t g_t gt 重复 3-7 步骤
AdaGrad 缺点是可能会使得学习率过早、过量的降低导致模型训练后期学习率太小较难找到最优解。
在PyTorch中AdaGrad优化法编程实践如下
def test02():# 1 初始化权重参数w torch.tensor([1.0], requires_gradTrue, dtypetorch.float32)loss ((w ** 2) / 2.0).sum()# 2 实例化优化方法adagrad优化方法optimizer torch.optim.Adagrad([w], lr0.01)# 3 第1次更新 计算梯度并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print(第1次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))# 4 第2次更新 计算梯度并对参数进行更新# 使用更新后的参数机选输出结果loss ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print(第2次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))结果显示
第1次: 梯度w.grad: 1.000000, 更新后的权重:0.990000
第2次: 梯度w.grad: 0.990000, 更新后的权重:0.9829653.3.4 RMSProp
RMSProp 优化算法是对 AdaGrad 的优化。最主要的不同是其使用指数加权平均梯度替换历史梯度的平方和。
其计算过程如下 初始化学习率 η、初始化权重参数w、小常数 σ 1e-10 初始化梯度累计变量 s 0 从训练集中采样 m 个样本的小批量计算梯度 g t g_t gt 使用指数加权平均累计历史梯度⊙ 表示各个分量相乘公式如下 s t s_t st β s t − 1 s_{t-1} st−1 (1-β) g t g_t gt⊙ g t g_t gt 学习率 η 的计算公式如下 η η s t σ η\over\sqrt{s_t}σ st ση 权重参数更新公式如下 w t w_t wt w t − 1 w_{t-1} wt−1 - η s t σ η\over\sqrt{s_t}σ st ση * g t g_t gt 重复 3-7 步骤
RMSProp 与 AdaGrad 最大的区别是对梯度的累积方式不同对于每个梯度分量仍然使用不同的学习率。
RMSProp 通过引入衰减系数β控制历史梯度对历史梯度信息获取的多少. 被证明在神经网络非凸条件下的优化更好学习率衰减更加合理一些。
需要注意的是AdaGrad 和 RMSProp 都是对于不同的参数分量使用不同的学习率如果某个参数分量的梯度值较大则对应的学习率就会较小如果某个参数分量的梯度较小则对应的学习率就会较大一些。
在PyTorch中RMSprop梯度优化法编程实践如下
def test03():# 1 初始化权重参数w torch.tensor([1.0], requires_gradTrue, dtypetorch.float32)loss ((w ** 2) / 2.0).sum()# 2 实例化优化方法RMSprop算法其中alpha对应betaoptimizer torch.optim.RMSprop([w], lr0.01, alpha0.9)# 3 第1次更新 计算梯度并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print(第1次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))# 4 第2次更新 计算梯度并对参数进行更新# 使用更新后的参数机选输出结果loss ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print(第2次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))结果显示
第1次: 梯度w.grad: 1.000000, 更新后的权重:0.968377
第2次: 梯度w.grad: 0.968377, 更新后的权重:0.9457883.3.5 Adam Momentum 使用指数加权平均计算当前的梯度值 AdaGrad、RMSProp 使用自适应的学习率 Adam优化算法Adaptive Moment Estimation自适应矩估计将 Momentum 和 RMSProp 算法结合在一起 修正梯度: 使⽤梯度的指数加权平均修正学习率: 使⽤梯度平⽅的指数加权平均 原理Adam 是结合了 Momentum 和 RMSProp 优化算法的优点的自适应学习率算法。它计算了梯度的一阶矩平均值和二阶矩梯度的方差的自适应估计从而动态调整学习率。 梯度计算公式 m t β 1 m t − 1 ( 1 − β 1 ) g t m_tβ_1m_{t−1}(1−β_1)g_t mtβ1mt−1(1−β1)gt s t β 2 s t − 1 ( 1 − β 2 ) g t 2 s_tβ_2s_{t−1}(1−β_2)gt^2 stβ2st−1(1−β2)gt2 m t ^ \hat{m_t} mt^ m t 1 − β 1 t m_t\over1−β_1^t 1−β1tmt, s t ^ \hat{s_t} st^ s t 1 − β 2 t s_t\over1−β_2^t 1−β2tst 权重参数更新公式: w t w_t wt w t − 1 w_{t−1} wt−1 − η s t ^ ϵ η\over\sqrt{\hat{s_t}}ϵ st^ ϵη m t ^ \hat{m_t} mt^
其中 m t m_t mt 是梯度的一阶矩估计 s t s_t st 是梯度的二阶矩估计$ \hat{m_t}$和 s t ^ \hat{s_t} st^ 是偏差校正后的估计。
在PyTroch中Adam梯度优化法编程实践如下
def test04():# 1 初始化权重参数w torch.tensor([1.0], requires_gradTrue)loss ((w ** 2) / 2.0).sum()# 2 实例化优化方法Adam算法其中betas是指数加权的系数optimizer torch.optim.Adam([w], lr0.01, betas[0.9, 0.99])# 3 第1次更新 计算梯度并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print(第1次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))# 4 第2次更新 计算梯度并对参数进行更新# 使用更新后的参数机选输出结果loss ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print(第2次: 梯度w.grad: %f, 更新后的权重:%f % (w.grad.numpy(), w.detach().numpy()))结果显示
第1次: 梯度w.grad: 1.000000, 更新后的权重:0.990000
第2次: 梯度w.grad: 0.990000, 更新后的权重:0.9800033.3.6 小结
优化算法优点缺点适用场景SGD简单、容易实现。收敛速度较慢容易震荡特别是在复杂问题中。用于简单任务或者当数据特征分布相对稳定时。Momentum可以加速收敛减少震荡特别是在高曲率区域。需要手动调整动量超参数可能会在小步长训练中过度更新。用于非平稳优化问题尤其是深度学习中的应用。AdaGrad自适应调整学习率适用于稀疏数据。学习率会在训练过程中逐渐衰减可能导致早期停滞。适合稀疏数据如 NLP 或推荐系统中的特征。RMSProp解决了 AdaGrad 学习率过早衰减的问题适应性强。需要选择合适的超参数更新可能会过于激进。适用于动态问题、非平稳目标函数如深度学习训练。Adam结合了 Momentum 和 RMSProp 的优点适应性强且稳定。需要调节更多的超参数训练过程中可能会产生较大波动。广泛适用于各种深度学习任务特别是非平稳和复杂问题。 简单任务和较小的模型SGD 或 Momentum 复杂任务或有大量数据Adam 是最常用的选择因其在大部分任务上都表现优秀 需要处理稀疏数据或文本数据Adagrad 或 RMSProp
4 学习率衰减优化方法
4.1 为什么要进行学习率优化
在训练神经网络时一般情况下学习率都会随着训练而变化。这主要是由于在神经网络训练的后期如果学习率过高会造成loss的振荡但是如果学习率减小的过慢又会造成收敛变慢的情况。
运行下面代码观察学习率设置不同对网络训练的影响
# x看成是权重y看成是loss下面通过代码来理解学习率的作用
def func(x_t):return torch.pow(2*x_t, 2) # y 4 x ^2# 采用较小的学习率梯度下降的速度慢
# 采用较大的学习率梯度下降太快越过了最小值点导致不收敛甚至震荡
def test():x torch.tensor([2.], requires_gradTrue)# 记录loss迭代次数画曲线iter_rec, loss_rec, x_rec list(), list(), list()# 实验学习率 0.01 0.02 0.03 0.1 0.2 0.3 0.4# lr 0.1 # 正常的梯度下降# lr 0.125 # 当学习率设置0.125 一下子求出一个最优解# x0 y0 在x0处梯度等于0 x的值xx-lr*x.grad就不用更新了# 后续再多少次迭代 都固定在最优点lr 0.2 # x从2.0一下子跨过0点到了左侧负数区域# lr 0.3 # 梯度越来越大 梯度爆炸max_iteration 4for i in range(max_iteration):y func(x) # 得出loss值y.backward() # 计算x的梯度print(Iter:{}, X:{:8}, X.grad:{:8}, loss:{:10}.format(i, x.detach().numpy()[0], x.grad.detach().numpy()[0], y.item()))x_rec.append(x.item()) # 梯度下降点 列表# 更新参数x.data.sub_(lr * x.grad) # x x - x.gradx.grad.zero_()iter_rec.append(i) # 迭代次数 列表loss_rec.append(y) # 损失值 列表# 迭代次数-损失值 关系图plt.subplot(121).plot(iter_rec, loss_rec, -ro)plt.grid()plt.xlabel(Iteration X)plt.ylabel(Loss value Y)# 函数曲线-下降轨迹 显示图x_t torch.linspace(-3, 3, 100)y func(x_t)plt.subplot(122).plot(x_t.numpy(), y.numpy(), labely 4*x^2)y_rec [func(torch.tensor(i)).item() for i in x_rec]print(x_rec---, x_rec)print(y_rec---, y_rec)# 指定线的颜色和样式-ro红色圆圈b-蓝色实线等plt.subplot(122).plot(x_rec, y_rec, -ro)plt.grid()plt.legend()plt.show()运行效果图如下
可以看出采用较小的学习率梯度下降的速度慢采用较大的学习率梯度下降太快越过了最小值点导致震荡甚至不收敛梯度爆炸。 4.2 等间隔学习率衰减
等间隔学习率衰减方式如下所示
在PyTorch中实现时使用
# step_size调整间隔数50
# gamma调整系数0.5
# 调整方式lr lr * gamma
optim.lr_scheduler.StepLR(optimizer, step_size, gamma0.1)具体使用方式如下
import torch
from torch import optim
import matplotlib.pyplot as pltdef test_StepLR():# 0.参数初始化LR 0.1 # 设置学习率初始化值为0.1iteration 10max_epoch 200# 1 初始化参数y_true torch.tensor([0])x torch.tensor([1.0])w torch.tensor([1.0], requires_gradTrue)# 2.优化器optimizer optim.SGD([w], lrLR, momentum0.9)# 3.设置学习率下降策略scheduler_lr optim.lr_scheduler.StepLR(optimizer, step_size50, gamma0.5)# 4.获取学习率的值和当前的epochlr_list, epoch_list [], []for epoch in range(max_epoch):lr_list.append(scheduler_lr.get_last_lr()) # 获取当前lrepoch_list.append(epoch) # 获取当前的epochfor i in range(iteration): # 遍历每一个batch数据loss (w*x-y_true)**2 # 目标函数optimizer.zero_grad()# 反向传播loss.backward()optimizer.step()# 更新下一个epoch的学习率scheduler_lr.step()# 5.绘制学习率变化的曲线plt.plot(epoch_list, lr_list, labelStep LR Scheduler)plt.xlabel(Epoch)plt.ylabel(Learning rate)plt.legend()plt.show() 4.3 指定间隔学习率衰减
指定间隔学习率衰减的效果如下
在PyTorch中实现时使用
# milestones设定调整轮次:[50, 125, 160]
# gamma调整系数
# 调整方式lr lr * gamma
optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma0.1, last_epoch-1) 具体使用方式如下所示
import torch
from torch import optim
import matplotlib.pyplot as pltdef test_MultiStepLR():torch.manual_seed(1)LR 0.1iteration 10max_epoch 200y_true torch.tensor([0])x torch.tensor([1.0])w torch.tensor([1.0], requires_gradTrue)optimizer optim.SGD([w], lrLR, momentum0.9)# 设定调整时刻数milestones [50, 125, 160]# 设置学习率下降策略scheduler_lr optim.lr_scheduler.MultiStepLR(optimizer, milestonesmilestones, gamma0.5)lr_list, epoch_list list(), list()for epoch in range(max_epoch):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)for i in range(iteration):loss (w*x-y_true)**2optimizer.zero_grad()# 反向传播loss.backward()# 参数更新optimizer.step()# 更新下一个epoch的学习率scheduler_lr.step()plt.plot(epoch_list, lr_list, labelMulti Step LR Scheduler\nmilestones:{}.format(milestones))plt.xlabel(Epoch)plt.ylabel(Learning rate)plt.legend()plt.show()4.4 按指数学习率衰减
按指数衰减调整学习率的效果如下
在PyTorch中实现时使用
# gamma指数的底
# 调整方式
# lr lr∗gamma^epoch
optim.lr_scheduler.ExponentialLR(optimizer, gamma)具体使用方式如下所示
import torch
from torch import optim
import matplotlib.pyplot as pltdef test_ExponentialLR():# 0.参数初始化LR 0.1 # 设置学习率初始化值为0.1iteration 10max_epoch 200# 1 初始化参数y_true torch.tensor([0])x torch.tensor([1.0])w torch.tensor([1.0], requires_gradTrue)# 2.优化器optimizer optim.SGD([w], lrLR, momentum0.9)# 3.设置学习率下降策略gamma 0.95scheduler_lr optim.lr_scheduler.ExponentialLR(optimizer, gammagamma)# 4.获取学习率的值和当前的epochlr_list, epoch_list list(), list()for epoch in range(max_epoch):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)for i in range(iteration): # 遍历每一个batch数据loss (w*x-y_true)**2optimizer.zero_grad()# 反向传播loss.backward()optimizer.step()# 更新下一个epoch的学习率scheduler_lr.step()# 5.绘制学习率变化的曲线plt.plot(epoch_list, lr_list, labelMulti Step LR Scheduler)plt.xlabel(Epoch)plt.ylabel(Learning rate)plt.legend()plt.show()4.5 小结
方法等间隔学习率衰减 (Step Decay)指定间隔学习率衰减 (Exponential Decay)指数学习率衰减 (Exponential Moving Average Decay)衰减方式固定步长衰减指定步长衰减平滑指数衰减历史平均考虑实现难度简单易实现相对简单容易调整需要额外历史计算较复杂适用场景大型数据集、较为简单的任务对训练平稳性要求较高的任务高精度训练避免过快收敛优点直观易于调试适用于大批量数据易于调试稳定训练过程平滑且考虑历史更新收敛稳定性较强缺点学习率变化较大可能跳过最优点在某些情况下可能衰减过快导致优化提前停滞超参数调节较为复杂可能需要更多的计算资源
5 正则化方法
5.1 什么是正则化 在设计机器学习算法时希望在新样本上的泛化能力强。许多机器学习算法都采用相关的策略来减小测试误差这些策略被统称为正则化神经网络强大的表示能力经常遇到过拟合所以需要使用不同形式的正则化策略目前在深度学习中使用较多的策略有范数惩罚DropOut特殊的网络层等接下来我们对其进行详细的介绍
5.2 Dropout正则化
在训练深层神经网络时由于模型参数较多在数据量不足的情况下很容易过拟合。Dropout中文翻译成随机失活是一个简单有效的正则化方法。 在训练过程中Dropout的实现是让神经元以超参数p丢弃概率的概率停止工作或者激活被置为0,未被置为0的进行缩放缩放比例为1/(1-p)。训练过程可以认为是对完整的神经网络的一些子集进行训练每次基于输入数据只更新子网络的参数在实际应用中Dropout参数p的概率通常取值在0.2到0.5之间 对于较小的模型或较复杂的任务丢弃率可以选择0.3或更小对于非常深的网络较大的丢弃率如0.5或0.6可能会有效防止过拟合实际应用中通常会在全连接层激活函数后之后添加Dropout层 在测试过程中随机失活不起作用 在测试阶段使用所有的神经元进行预测以获得更稳定的结果直接使用训练好的模型进行测试由于所有的神经元都参与计算输出的期望值会比训练阶段高。测试阶段的期望输出是 E[x_test] x测试/推理模式model.eval() 缩放的必要性 在训练阶段将参与计算的神经元的输出除以(1-p)经过Dropout后的期望输出变为 E[x_dropout] [(1-p) * x] / (1-p) x与测试阶段的期望输出一致训练模型model.train()
我们通过一段代码观察下dropout的效果
import torch
import torch.nn as nndef test():# 初始化随机失活层dropout nn.Dropout(p0.4)# 初始化输入数据:表示某一层的weight信息inputs torch.randint(0, 10, size[1, 4]).float()layer nn.Linear(4,5)y layer(inputs)y torch.relu(y)print(未失活FC层的输出结果\n, y)y dropout(y)print(失活后FC层的输出结果\n, y)输出结果
未失活FC层的输出结果tensor([[0.0000, 1.8033, 1.4608, 4.5189, 6.9116]], grad_fnReluBackward0)
失活后FC层的输出结果tensor([[0.0000, 3.0055, 2.4346, 7.5315, 11.5193]], grad_fnMulBackward0)上述代码将Dropout层的丢弃概率p设置为0.4此时经过Dropout层计算的张量中就出现了很多0, 未变为0的按照1/(1-0.4)进行处理。
5.3 批量归一正则化(Batch Normalization)
在神经网络的训练过程中流经网络的数据都是一个batch每个batch之间的数据分布变化非常剧烈这就使得网络参数频繁的进行大的调整以适应流经网络的不同分布的数据给模型训练带来非常大的不稳定性使得模型难以收敛。如果我们对每一个batch的数据进行标准化之后数据分布就变得稳定参数的梯度变化也变得稳定有助于加快模型的收敛。
通过标准化每一层的输入使其均值接近0方差接近1从而加速训练并提高泛化能力。 先对数据标准化再对数据重构缩放平移写成公式如下所示 λ和β是可学习的参数它相当于对标准化后的值做了一个线性变换λ为系数β为偏置
eps 通常指为 1e-5避免分母为 0
E(x) 表示变量的均值
Var(x) 表示变量的方差
批量归一化的步骤如下 计算均值和方差对于每个神经元即每一层的输入特征计算该特征在一个小批量batch上的均值 μ B μ_B μB 和方差 σ B 2 \sigma_B^2 σB2它们的计算公式如下 μ B 1 m ∑ i 1 m x i μ_B\frac{1}{m} \sum_{i1}^{m} x_i μBm1∑i1mxi σ B 2 1 m ∑ i 1 m ( x i − μ B ) 2 σ_B^2\frac{1}{m} \sum_{i1}^{m} (x_i - \mu_B)^2 σB2m1∑i1m(xi−μB)2 其中 x i x_i xi 表示小批量中的第 i i i 个样本 m m m 是小批量的样本数量。 标准化然后对每个样本的输入进行标准化得到归一化的输出 x ^ i x i − μ B σ B 2 ϵ \hat{x}_i \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 \epsilon}} x^iσB2ϵ xi−μB 其中 ϵ ϵ ϵ 是一个小常数用来避免除以零的情况。 缩放和平移为了让网络能够恢复其学习能力BN 层引入了两个可训练的参数 γ γ γ 和 β β β分别用于缩放和平移 y i γ x ^ i β y_i \gamma \hat{x}_i β yiγx^iβ 其中 γ γ γ 和 β β β 是可学习的参数通过 γ 和 βBN 层不再是简单的将每一层输入强行变为标准正态分布而是允许网络学习更适合于该层的输入分布规范化操作会丢失原始输入的一些信息而 γ γ γ 和 β β β 可以弥补这种信息损失。
批量归一化的作用 **减少内部协方差偏移**通过对每层的输入进行标准化减少了输入数据分布的变化从而加速了训练过程并使得网络在训练过程中更加稳定。 加速训练 在没有批量归一化的情况下神经网络的训练通常会很慢尤其是深度网络。因为在每层的训练过程中输入数据的分布特别是前几层会不断变化这会导致网络学习速度缓慢。批量归一化通过确保每层的输入数据在训练时分布稳定有效减少了这种变化从而加速了训练过程。 **起到正则化作用**批量归一化可以视作一种正则化方法因为它引入了对训练样本的噪声不同批次的统计信息不同批次较小的均值和方差估计会更加不准确使得模型不容易依赖特定的输入特征从而起到一定的正则化效果减少了对其他正则化技术如Dropout的需求。 **提升泛化能力**由于其正则化效果批量归一化能帮助网络在测试集上取得更好的性能。
批量归一化层在计算机视觉领域使用较多
Batch Normalization 的使用步骤
在网络层后添加 BN 层 通常BN 层会添加在卷积层 (Conv2d) 或全连接层 (Linear) 之后激活函数之前。例如Conv2d - BN - ReLU 或者 Linear - BN - ReLU。 训练时model.train() BN 层会计算当前批次的均值 μ μ μ 和方差 σ 2 σ² σ2。然后利用这两个统计量对当前批次的数据进行规范化。规范化后的数据会被缩放 γ γ γ 和平移 β β β。同时BN 层还会维护一个全局均值和全局方差的移动平均值用于推理阶段。 推理时model.eval() 推理时不会再使用当前批次的均值和方差而是使用训练阶段计算的全局均值和全局方差。同样规范化后的数据会被缩放 γ γ γ 和平移 β β β。
import torch
import torch.nn as nn
BatchNorm1d主要应用于全连接层或处理一维数据的网络例如文本处理。它接收形状为 (N, num_features) 的张量作为输入。
BatchNorm2d主要应用于卷积神经网络处理二维图像数据或特征图。它接收形状为 (N, C, H, W) 的张量作为输入。
BatchNorm3d主要用于三维卷积神经网络 (3D CNN)处理三维数据例如视频或医学图像。它接收形状为 (N, C, D, H, W) 的张量作为输入。
def tes01():# 创建测试样本, 假设是经过卷积层(Conv2d)处理后的特征图# (N, C, H, W): 一张图, 两个通道, 每个通道3行4列# 可以创建1个样本, 图像的BN是对每个通道的特征图(行列数据)进行标准化input_2d torch.randn(size(1, 2, 3, 4))print(input--, input_2d)# num_features输入特征数# eps非常小的浮点数防止除以0的错误# momentum动量系数# affine默认为Trueγ和β被使用让BN层更加灵活bn2d nn.BatchNorm2d(num_features2, eps1e-05, momentum0.1, affineTrue) output bn2d(input_2d)print(output--, output)print(output.size())print(bn2d.weight)print(bn2d.bias) def tes02():# 创建测试样本# 2个样本, 1个特征# 不能创建1个样本, 无法统计均值和方差input_1d torch.randn(size(2, 2)) # 创建线性层对象linear1 nn.Linear(in_features2, out_features3)# 创建BN层对象# num_features输入特征数bn1d nn.BatchNorm1d(num_features3) # 20 output featuresoutput_1d linear1(input_1d)# 进行批量归一化output bn1d(output_1d) print(output--, output)print(output.size()) # (32, 20)输出结果
test01:
input_2d-- tensor([[[[-0.2751, -1.2183, -0.5106, -0.1540],[-0.4585, -0.5989, -0.6063, 0.5986],[-0.4745, 0.1496, -1.1266, -1.2377]],[[ 0.2580, 1.2065, 1.4598, 0.8387],[-0.4586, 0.8938, -0.3328, 0.1192],[-0.3265, -0.6263, 0.0419, -1.2231]]]])
output-- tensor([[[[ 0.4164, -1.3889, -0.0343, 0.6484],[ 0.0655, -0.2032, -0.2175, 2.0889],[ 0.0349, 1.2294, -1.2134, -1.4262]],[[ 0.1340, 1.3582, 1.6853, 0.8835],[-0.7910, 0.9546, -0.6287, -0.0452],[-0.6205, -1.0075, -0.1449, -1.7779]]]],grad_fnNativeBatchNormBackward0)
torch.Size([1, 2, 3, 4])
Parameter containing:
tensor([1., 1.], requires_gradTrue)
Parameter containing:
tensor([0., 0.], requires_gradTrue)test02:
output-- tensor([[-0.9998, 1.0000, 1.0000],[ 0.9998, -1.0000, -1.0000]], grad_fnNativeBatchNormBackward0)
torch.Size([2, 3])
文章转载自: http://www.morning.jtsdk.cn.gov.cn.jtsdk.cn http://www.morning.bqpg.cn.gov.cn.bqpg.cn http://www.morning.gmrxh.cn.gov.cn.gmrxh.cn http://www.morning.tsxg.cn.gov.cn.tsxg.cn http://www.morning.trsdm.cn.gov.cn.trsdm.cn http://www.morning.pznnt.cn.gov.cn.pznnt.cn http://www.morning.qwmdx.cn.gov.cn.qwmdx.cn http://www.morning.qrksj.cn.gov.cn.qrksj.cn http://www.morning.dmzmy.cn.gov.cn.dmzmy.cn http://www.morning.rrqgf.cn.gov.cn.rrqgf.cn http://www.morning.ygwbg.cn.gov.cn.ygwbg.cn http://www.morning.cykqg.cn.gov.cn.cykqg.cn http://www.morning.xsbhg.cn.gov.cn.xsbhg.cn http://www.morning.twfdm.cn.gov.cn.twfdm.cn http://www.morning.grbgn.cn.gov.cn.grbgn.cn http://www.morning.bpmfl.cn.gov.cn.bpmfl.cn http://www.morning.qbtj.cn.gov.cn.qbtj.cn http://www.morning.jsphr.cn.gov.cn.jsphr.cn http://www.morning.dyxlm.cn.gov.cn.dyxlm.cn http://www.morning.c7497.cn.gov.cn.c7497.cn http://www.morning.lqznq.cn.gov.cn.lqznq.cn http://www.morning.zrdqz.cn.gov.cn.zrdqz.cn http://www.morning.ldnrf.cn.gov.cn.ldnrf.cn http://www.morning.xqknl.cn.gov.cn.xqknl.cn http://www.morning.wqcz.cn.gov.cn.wqcz.cn http://www.morning.ho-use.cn.gov.cn.ho-use.cn http://www.morning.rjmb.cn.gov.cn.rjmb.cn http://www.morning.clpdm.cn.gov.cn.clpdm.cn http://www.morning.yjprj.cn.gov.cn.yjprj.cn http://www.morning.htbbp.cn.gov.cn.htbbp.cn http://www.morning.bfjtp.cn.gov.cn.bfjtp.cn http://www.morning.trsfm.cn.gov.cn.trsfm.cn http://www.morning.mtdfn.cn.gov.cn.mtdfn.cn http://www.morning.qrqdr.cn.gov.cn.qrqdr.cn http://www.morning.ktmbr.cn.gov.cn.ktmbr.cn http://www.morning.qywfw.cn.gov.cn.qywfw.cn http://www.morning.cljpz.cn.gov.cn.cljpz.cn http://www.morning.fppzc.cn.gov.cn.fppzc.cn http://www.morning.jcxyq.cn.gov.cn.jcxyq.cn http://www.morning.frfpx.cn.gov.cn.frfpx.cn http://www.morning.wwsgl.com.gov.cn.wwsgl.com http://www.morning.ryyjw.cn.gov.cn.ryyjw.cn http://www.morning.ffcsr.cn.gov.cn.ffcsr.cn http://www.morning.nlkm.cn.gov.cn.nlkm.cn http://www.morning.pcgrq.cn.gov.cn.pcgrq.cn http://www.morning.wkws.cn.gov.cn.wkws.cn http://www.morning.lsgsn.cn.gov.cn.lsgsn.cn http://www.morning.rfwrn.cn.gov.cn.rfwrn.cn http://www.morning.psdbf.cn.gov.cn.psdbf.cn http://www.morning.hypng.cn.gov.cn.hypng.cn http://www.morning.zwzwn.cn.gov.cn.zwzwn.cn http://www.morning.kszkm.cn.gov.cn.kszkm.cn http://www.morning.clxpp.cn.gov.cn.clxpp.cn http://www.morning.rjmd.cn.gov.cn.rjmd.cn http://www.morning.qrqcr.cn.gov.cn.qrqcr.cn http://www.morning.ffydh.cn.gov.cn.ffydh.cn http://www.morning.lysrt.cn.gov.cn.lysrt.cn http://www.morning.xbxks.cn.gov.cn.xbxks.cn http://www.morning.xqgh.cn.gov.cn.xqgh.cn http://www.morning.ljcjc.cn.gov.cn.ljcjc.cn http://www.morning.rzscb.cn.gov.cn.rzscb.cn http://www.morning.rwzkp.cn.gov.cn.rwzkp.cn http://www.morning.ysbhj.cn.gov.cn.ysbhj.cn http://www.morning.rxnl.cn.gov.cn.rxnl.cn http://www.morning.ktdqu.cn.gov.cn.ktdqu.cn http://www.morning.jmllh.cn.gov.cn.jmllh.cn http://www.morning.rszwc.cn.gov.cn.rszwc.cn http://www.morning.krzrg.cn.gov.cn.krzrg.cn http://www.morning.nkyqh.cn.gov.cn.nkyqh.cn http://www.morning.mxnfh.cn.gov.cn.mxnfh.cn http://www.morning.fmtfj.cn.gov.cn.fmtfj.cn http://www.morning.ywqsk.cn.gov.cn.ywqsk.cn http://www.morning.rjyd.cn.gov.cn.rjyd.cn http://www.morning.wdlyt.cn.gov.cn.wdlyt.cn http://www.morning.nlbhj.cn.gov.cn.nlbhj.cn http://www.morning.ktnmg.cn.gov.cn.ktnmg.cn http://www.morning.fewhope.com.gov.cn.fewhope.com http://www.morning.xstfp.cn.gov.cn.xstfp.cn http://www.morning.swzpx.cn.gov.cn.swzpx.cn http://www.morning.jnzfs.cn.gov.cn.jnzfs.cn