三、神经网络——网络优化方法

三、网络优化方法

1.梯度下降算法

  • 梯段下降算法是一种寻找使损失函数最小化的方法,从数学上的角度来看,梯度的方向是函数增长速度最快的方向,那么梯度的反方向就是函数减少最快的方向,所以有Wijnew=Wijold−η∂E∂WijW_{ij}^{new} = W_{ij}^{old}-\eta\frac{\partial E}{\partial W_{ij}}Wijnew=WijoldηWijE

    • 其中,η\etaη是学习率,如果学习率太小,那么每次训练之后得到的效果都太小,增大训练的时间成本;如果学习率太大,那就有可能直接跳过最优解,进入无限的训练中。解决的方法就是,学习率也需要随着训练的进行而变化
  • 在进行模型训练的时候,有三个基础的概念

    • EpochEpochEpoch:使用全部数据对模型进行一次完整训练,训练轮次
    • Batch_sizeBatch\_sizeBatch_size:使用训练集中的小部分样本对模型权重进行以此反向传播的参数更新,每次训练每批次样本的数量(越大越好)
    • IteraionIteraionIteraion:使用一个Batch数据对模型进行一次参数更新的过程
    • eg.eg.eg.:假设数据集有500005000050000个训练样本,现在选择BatchSize=256Batch Size= 256BatchSize=256对模型进行训练,每个EpochEpochEpoch要训练的图片数量为500005000050000,训练集具有BatchBatchBatch个数为50000/256+1=19650000/256 + 1 = 19650000/256+1=196;每个EpochEpochEpoch具有的IterationIterationIteration个数为196196196101010EpochEpochEpoch具有的IterationIterationIteration个数为196019601960
  • 在深度学习中,梯度下降的几种方式的根本区别就在于Batch Size不同

    梯度下降方式Training Set SizeBatch SizeNumber of Batch
    BGDNN1
    SGDN1N
    Mini-BatchNBN / B + 1
    • 注:N/ B+ 1是针对未整除的情况。整除则是 N/ B
    • 在工作的时候通常使用的是 Mini-Batch

2.反向传播算法过程

(1)反向传播(BP算法)

  • 前向传播:指的是数据输入的神经网络中,逐层向前传输,一直运算到输出层为止
  • 反向传播(BackPropagation):利用损失函数ERROR,从后往前,结合梯度下降算法,依次求各个参数的偏导并进行参数更新
  • 解释:
    1. 前向传播:获取预测结果
    2. 计算损失:交叉熵/MSE(先计算W3W_3W3,再计算W2W_2W2,最后计算W1W_1W1)
    3. 反向传播:利用梯度下降算法对参数进行更新
for _ in range(epochs):for train_x, train_y in dataloader:# 将一个batch的训练数据送入模型y_pred = model(train_x.type(torch.float32))# 计算损失值loss = criterion(y_pred, train_y, reshape(-1,1).type(torch.float32))total_loss += loss.item()train_sample += len(train_y)# 梯度清零optimizer.zero_grad()# 自动微分loss.backward()# 更新参数optimizer.step()

3.梯度下降的优化方法

  • 梯度下降优化算法中,可能会碰到以下情况:

    • 碰到平缓区域,梯度值较小,参数优化变慢
    • 碰到鞍点,梯度为0,参数无法优化
    • 碰到局部最小值,参数不是最优
  • 对于这些问题,出现了一些对梯度下降算法的优化方法,例如:Momentum, AgaGrad,PMSprop,Adam等

(1)指数加权平均

  • 指数移动加权平均:参考各数值,并且各数值的权重都不同,距离越远的数字对平均数计算的贡献就越小(权重较小),距离越近则对平均数的计算贡献就越大(权重越大)
  • 计算公式:st={Y1,t=0β⋅st−1+(1−β)⋅Yt,t>0{s}_t = \begin{cases} \displaystyle Y_1, & t = 0 \\ \displaystyle \beta \cdot {s}_{t-1} + (1 - \beta) \cdot Y_t, & t > 0 \end{cases}st={Y1,βst1+(1β)Yt,t=0t>0
    • StS_tSt表示指数加权平均值
    • YtY_tYt表示ttt时刻的值
    • β\betaβ调整权重参数,该值越大平均数越平缓

(2)动量算法Momentum

  • 梯度计算公式:Dt=β⋅St−1+(1−β)⋅WtD_t = \beta \cdot S_{t - 1} + (1-\beta) \cdot W_tDt=βSt1+(1β)Wt
    • St−1S_{t - 1}St1表示;表示梯度移动加权平均值
    • WtW_tWt表示当前时刻的梯度值
    • DtD_tDt为当前时刻的梯度值
    • β\betaβ为权重系数
    • 示例:权重β\betaβ为0.9, 则第一次梯度值S1=D1=W1S_1 = D_1 = W_1S1=D1=W1;第二次梯度值D2=S2=0.9×S1+W2×0.1D_2 = S_2 = 0.9 \times S_1 + W_2 \times0.1D2=S2=0.9×S1+W2×0.1;第三次梯度值D3=S3=0.9×S2+W3×0.1D_3 = S_3 = 0.9 \times S_2 + W_3 \times 0.1D3=S3=0.9×S2+W3×0.1;第四次梯度值D4=S4=0.9×S3+W4×0.1D_4 = S_4 = 0.9 \times S_3 + W_4 \times 0.1D4=S4=0.9×S3+W4×0.1
  • 梯度下降公式中梯度的计算,就不再是当前时刻t的梯度值,而是历史梯度值的指数移动加权平均值,公式修改为:Wt+1=Wt−α⋅DtW_{t + 1} = W_t - \alpha \cdot D_tWt+1=WtαDt

拓展:Monmentum优化方法是如何一定程度上克服“平缓”,“鞍点”的问题呢?

  • 当处于鞍点位置时,由于当前的梯度为0,参数无法更新。但是Momentum动量梯度下降算法已经在先前累计了一些梯度值,很有可能使得跨过鞍点
  • 由于mini-batch普通的梯度下降算法,每次选取少数的样本梯度确定前进方向,可能会出现震荡,使得训练时间变长。Momentum使用移动加权平均,平滑了梯度的变化,使得前进方向更加平缓,有利于加快训练过程
"""加了动量之后的结果"""import torchw = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)loss = ((w ** 2)*0.5).sum()optimizer = torch.optim.SGD([w], lr = 0.01, momentum=0.9)optimizer.zero_grad()
loss.backward()
optimizer.step()print("第一次更新(加了动量之后)梯度:",w.grad)
print("第一次更新(加了动量之后)w:",w.detach())loss = ((w ** 2)*0.5).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()print("第二次更新(加了动量之后)梯度:",w.grad)
print("第二次更新(加了动量之后)w:",w.detach()) # tensor([0.9711])改变了,没加动量时 tensor([0.9801])"""tensor([0.9900])--->tensor([0.9711])   减少得更多,更新得更加快一点"""

输出结果:

第一次更新(加了动量之后)梯度: tensor([1.])
第一次更新(加了动量之后)w: tensor([0.9900])
第二次更新(加了动量之后)梯度: tensor([0.9900])
第二次更新(加了动量之后)w: tensor([0.9711])

(3)AdaGrad

  • AdaGrad通过对不同的参数分量使用不同的学习率,AdaGrad的学习率总体会逐渐减小,计算步骤如下

    1. 初始化学习率α\alphaα,初始化参数θ\thetaθ(weight&bias)小常数σ=1e−6\sigma = 1e - 6σ=1e6(放在分母上,防止分母为0)

    2. 初始化梯度累计变量s=0s = 0s=0

    3. 从训练集中采样mmm个样本的小批量,计算梯度ggg

    4. 累积平方梯度s=s+g⊙g{s} = {s} + {g} \odot {g}s=s+gg⊙\odot表示各个分量相乘

    • 学习率α\alphaα的计算公式如下:α=αs+σ\alpha = \frac{\alpha}{\sqrt s + \sigma}α=s+σα

    • 参数更新公式如下:θ=θ−αs+σ⋅g\theta = \theta - \frac{\alpha}{\sqrt s + \sigma} \cdot gθ=θs+σαg

重复2-4步骤,即可完成网络训练

  • AdaGrad缺点:可能会使得学习率过早,过量的降低(学习率太小了,则更新速度变慢了,迭代相同次数就不能够到最优解),导致训练后期学习率大小较难找到最优解
import torchw = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
loss = ((w ** 2)*0.5).sum()optimizer = torch.optim.Adagrad([w], lr = 0.01)optimizer.zero_grad()
loss.backward()print("第一次更新  梯度:",w.grad) # 获取梯度的值
print("第一次更新  w:",w.detach()) # 获取w的值# 再次更新参数
loss = ((w ** 2)*0.5).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()print("第二次更新  梯度:",w.grad) # 获取梯度的值
print("第二次更新  w:",w.detach()) # 获取w的值

输出结果:

第一次更新  梯度: tensor([1.])
第一次更新  w: tensor([1.])
第二次更新  梯度: tensor([1.])
第二次更新  w: tensor([0.9900])

(4)RMSProp

  • RMSProp优化算法是对AdaGrad的优化,最主要的不同是,其使用指数移动加权平均梯度替换历史梯度的平方和。计算过程如下:

    1. 初始化学习率α\alphaα,初始化参数θ\thetaθ,小常数σ=1e−6\sigma = 1e-6σ=1e6
    2. 初始化参数θ\thetaθ
    3. 初始化梯度累计变量sss
    4. 从训练集中采样mmm个样本的小批量,计算梯度ggg
    5. 使用指数移动平均累积历史梯度,公式如下:s=β⋅s+(1−β)g⊙gs = \beta \cdot s + (1 - \beta)g \odot gs=βs+(1β)gg
    • 学习率α\alphaα的计算公式如下:α=αs+σ\alpha = \frac{\alpha}{\sqrt s + \sigma}α=s+σα
    • 参数更新公式如下:θ=θ−αs+σ⋅g\theta = \theta - \frac{\alpha}{\sqrt s + \sigma} \cdot gθ=θs+σαg
import torchw = torch.tensor([0.1], requires_grad=True, dtype = torch.float32)
loss = ((w ** 2)*0.5).sum()optimizer = torch.optim.RMSprop([w], lr = 0.01, alpha = 0.9)optimizer.zero_grad()
loss.backward()print("第一次更新 梯度:", w.grad)
print("第一次更新 w:", w.detach())# 再次更新参数
loss = ((w ** 2)*0.5).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()print("第二次更新  梯度:",w.grad) # 获取梯度的值
print("第二次更新  w:",w.detach()) # 获取w的值

输出结果:

第一次更新 梯度: tensor([0.1000])
第一次更新 w: tensor([0.1000])
第二次更新  梯度: tensor([0.1000])
第二次更新  w: tensor([0.0684])

4.学习率衰减方法

  • 通常是和 动量算法Momentum 组合在一起
  • 后面学习中,通常使用指定间隔学习率衰减

(1)等间隔学习率衰减

import torch
import matplotlib.pyplot as plot# 参数初始化
LR = 0.1
iteration = 100
epochs = 200
# 网络数据初始化
x = torch.tensor([1.0])
w = torch.tensor([1.0], requires_grad = True)
y = torch.tensor([1.0])
# 优化器
optimizer = torch.optim.SGD([w], lr = LR, momentum=0.9)
# 学习率策略
scheduler_lr = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma = 0.8)
# 遍历轮次
epoch_list = []
lr_list = []
for epoch in range(epochs):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)# 遍历batchfor i in range(iteration):# 计算损失loss = ((w*x-y)**2)*0.5# 更新参数optimizer.zero_grad()loss.backward()optimizer.step()# 更新lrscheduler_lr.step()
# 绘制结果
plt.plot(epoch_list, lr_list)
plt.grid()
plt.show()

(2)指定间隔学习率衰减

import torch
import matplotlib.pyplot as plot# 参数初始化
LR = 0.1
iteration = 100
epochs = 200
# 网络数据初始化
x = torch.tensor([1.0])
w = torch.tensor([1.0], requires_grad = True)
y = torch.tensor([1.0])
# 优化器
optimizer = torch.optim.SGD([w], lr = LR, momentum=0.9)
# 学习率策略
scheduler_lr = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones = [20, 60, 90, 135, 180], gamma = 0.8)
# 遍历轮次
epoch_list = []
lr_list = []
for epoch in range(epochs):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)# 遍历batchfor i in range(iteration):# 计算损失loss = ((w*x-y)**2)*0.5# 更新参数optimizer.zero_grad()loss.backward()optimizer.step()# 更新lrscheduler_lr.step()
# 绘制结果
plt.plot(epoch_list, lr_list)
plt.grid()
plt.show()

(3)按指数学习率衰减

  • 这种策略用得很少,一般不会选择
  • gamma值通常是小于1,它是指 指数的底
  • 调整方式:lr=lr⋅gammaepochlr = lr \cdot gamma^{epoch}lr=lrgammaepoch
import torch
import matplotlib.pyplot as plot# 参数初始化
LR = 0.1
iteration = 100
epochs = 200
# 网络数据初始化
x = torch.tensor([1.0])
w = torch.tensor([1.0], requires_grad = True)
y = torch.tensor([1.0])
# 优化器
optimizer = torch.optim.SGD([w], lr = LR, momentum=0.9)
# 学习率策略
scheduler_lr = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma = 0.8)
# 遍历轮次
epoch_list = []
lr_list = []
for epoch in range(epochs):lr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)# 遍历batchfor i in range(iteration):# 计算损失loss = ((w*x-y)**2)*0.5# 更新参数optimizer.zero_grad()loss.backward()optimizer.step()# 更新lrscheduler_lr.step()
# 绘制结果
plt.plot(epoch_list, lr_list)
plt.grid()
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91027.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML/JOSN复习总结

HTML 基础 什么是 HTML? 1.HTML是一门语言,所有的网页都是用HTML这门语言编写出来的 2.HTML(HyperText Markup Language):超文本标记语言。 >超文本:超越了文本的限制,比普通文本更强大。除了文字信息,还可以定义图片、音频、视频等内…

Golang中的内置类型

A. int B. string C. struct D. array 首先,内置类型是指不需要引入任何关于这些数据类型的包,就可以引用的数据类型。那么,内置类型主要包括基本类型,复合类型,控制并发,高级抽象,特殊类型。…

通过命名空间引用了 Application 类,php不会自动包含路径文件吗?

示例代码:报错提示找不到Application类 use mvc\core\Application;$app new Application(); // 定义路由 $app->get(/, HomeControllerindex); $app->get(/user, UserControllershow); $app->post(/user, UserControllercreate);// 运行应用 $app->run…

PlantUML 基础使用技术文档

目录 摘要 1. 什么是 PlantUML 2. 安装与环境配置 2.1 本地使用 2.2 在线使用 3. 基本语法 3.1 示例:系统架构图 3.2 常用元素 4. 渲染方式 4.1 VSCode 4.2 在线渲染 4.3 生成图片 5. 推荐实践 6. 常见图类型 7. 进阶功能 8. 典型应用场景 摘要 Pl…

Android Notification 通过增加addAction 跳转回Service重新执行逻辑

1.场景描述在App内升级过程中,apk下载过程中网络波动导致连接超时,下载失败后Service生命周期结束。前台通知也被清除。2.解决思路在通知栏中增加重试按钮重启下载服务。3.代码NotificationManager mNotificationManager (NotificationManager) getSy…

带货视频评论的用户洞察 科大讯飞AI算法赛 Datawhale AI夏令营

赛题 2025 iFLYTEK AI开发者大赛https://challenge.xfyun.cn/topic/info?typevideo-comment-insight 一、赛事背景 在电商直播爆发式增长的数字化浪潮下,短视频平台积累了海量带货视频及用户互动数据。这些数据不仅是消费者对商品体验的直接反馈,更蕴…

JAVA生成PDF(itextpdf)

java生成PDF有多种方式&#xff0c;比如itextpdf、 Apache PDFBox、Flying Saucer (XHTMLRenderer)、 OpenPDF等。今天要介绍的是itextpdf&#xff0c;及在开发过程中处理的问题。1. 引入POM<!--PDF导出POM--><dependency><groupId>com.itextpdf</groupId…

[爬虫知识] 深入理解多进程/多线程/协程的异步逻辑

相关爬虫实战案例&#xff1a;[爬虫实战] 多进程/多线程/协程-异步爬取豆瓣Top250 相关爬虫专栏&#xff1a;JS逆向爬虫实战 爬虫知识点合集 爬虫实战案例 逆向知识点合集 前言&#xff1a; 面对海量的目标数据&#xff0c;传统单线程、同步的爬取方式往往效率低下&#x…

Oracle RAC 11.2.0.4 更新SYSASM和SYS密码

前言 从技术角度看&#xff0c;SYSASM是Oracle 10g R2引入的ASM管理员角色&#xff0c;而SYS是数据库实例的超级用户&#xff0c;SYS账户无法管理ASM磁盘组。SYSASM权限是集群级别的&#xff0c;比如在添加磁盘组时&#xff0c;这个操作会影响所有节点&#xff1b;而SYS用户的权…

Vue》》总结

官网 vue路由的query参数、mixin 混入 vue cli 脚手架之配置代理 VUE SAP、 MPA&#xff0c;&#xff0c;组件开发、VDOM、双向数据绑定 Vue Props 、Mixin 、路由守卫 vue router query参数 Vue props以及其他通信方式, vue响应式 原理 追加响应式数据&#xff0c;数组响应式 …

Nginx 中的负载均衡策略

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;广泛用于负载均衡场景。它支持多种负载均衡策略&#xff0c;可以帮助你优化资源利用、提高响应速度和增加系统的可用性。以下是 Nginx 中几种常见的负载均衡策略及其配置方法&#xff1a; 1. 轮询&#xff08;Round Rob…

用 Python 将分组文本转为 Excel:以四级词汇为例的实战解析

一、背景引入&#xff1a;从“人工整理”到“自动化处理”的转变 在英语学习过程中&#xff0c;我们经常会接触各种分组整理的词汇表&#xff0c;比如“Group1”对应一组单词及释义&#xff0c;随后是“Group2”、“Group3”等等。如果你下载了一个 .txt 格式的四级词汇表&…

Ffmpeg滤镜

打开设备 添加滤镜 循环录制文件 #include "libavdevice/avdevice.h" #include "libavformat/avformat.h" #include "libavcodec/avcodec.h" #include "libavfilter/avfilter.h" #include "libavfilter/buffersink.h" #incl…

HarmonyOS AI辅助编程工具(CodeGenie)UI生成

UI Generator基于BitFun Platform AI能力平台&#xff0c;用于快速生成可编译、可运行的HarmonyOS UI工程&#xff0c;支持基于已有UI布局文件&#xff08;XML&#xff09;&#xff0c;快速生成对应的HarmonyOS UI代码&#xff0c;其中包含HarmonyOS基础工程、页面布局、组件及…

【第三节】ubuntu server配置远程连接

首先在ubuntu server中查看ip&#xff0c;打开虚拟机&#xff0c;输入ip addr show ,这个命令很好记&#xff0c;几乎就是英文自然语言 下面我们准备远程连接工具&#xff0c;我选择的开源的ET&#xff0c;全称是electerm,圈起来的是必须输入的内容&#xff0c;输入完成后点击保…

CCS-MSPM0G3507-7-模块篇-MPU6050的基本使用

前言本篇我们接收对MPU6050的基本使用&#xff0c;获取ID&#xff0c;通过IIC协议获取寄存器的值&#xff0c;至于高级滤波算法&#xff0c;比如卡尔曼滤波&#xff0c;或者上面的&#xff0c;后面再更新基本配置最好选择PA0和PA1&#xff0c;5V开漏然后给上代码MPU6050.c#incl…

spring-ai agent概念

目录agent 概念理解记忆能力工具计划agent 概念理解 agent 智能体&#xff0c;突出智能 大模型的感觉 告诉你怎么做&#xff08;也不一定正确&#xff09;不会帮你做 Agent的感觉 直接准确的帮你做完&#xff08;比如&#xff0c;告诉 AI Agent 帮忙下单一份外卖&#xff0c…

NO.4数据结构数组和矩阵|一维数组|二维数组|对称矩阵|三角矩阵|三对角矩阵|稀疏矩阵

数组的储存 【定义】 数组&#xff1a; 由 n&#xff08;≥1&#xff09; 个相同类型的数据元素构成的有限序列&#xff0c; 是线性表的推广。 一旦被定义&#xff0c; 维数和长度就不可再改变&#xff0c; 一般对其只有元素的存取和修改操作。 一维数组 Arr[a0,…,an−1] Arr[…

如何把Arduino IDE中ESP32程序bin文件通过乐鑫flsah_download_tool工具软件下载到ESP32中

目录前言获取Arduino IDE中ESP32程序bin文件flsah_download_tool工具软件下载程序bin文件到ESP32中总结前言 Arduino IDE丰富的驱动库给ESP32的开发带来了很多便利&#xff0c;当我们下载程序的时候&#xff0c;直选选择好ESP32开发板型号和端口号即可下载程序到开发板中&…