经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 大数据/云/AI » 人工智能基础 » 查看文章
深度学习(十四)——优化器
来源:cnblogs  作者:码头牛牛  时间:2023/9/15 13:29:14  对本文有异议

反向传播可以求出神经网路中每个需要调节参数的梯度(grad),优化器可以根据梯度进行调整,达到降低整体误差的作用。下面我们对优化器进行介绍。

1. 如何使用优化器

官方文档:torch.optim — PyTorch 2.0 documentation

(1)构造优化器

举个栗子:

  1. optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
  2. optimizer = optim.Adam([var1, var2], lr=0.0001)
  • 首先选择优化器的算法optim.SGD

  • 之后在优化器中放入模型参数model.parameters(),这一步是必备

  • 还可在函数中设置一些参数,如学习速率lr=0.01(这是每个优化器中几乎都会有的参数)

(2)调用优化器中的step方法

step()方法就是利用我们之前获得的梯度,对神经网络中的参数进行更新。

举个栗子:

  1. for input, target in dataset:
  2. optimizer.zero_grad()
  3. output = model(input)
  4. loss = loss_fn(output, target)
  5. loss.backward()
  6. optimizer.step()
  • 步骤optimizer.zero_grad()是必选的

  • 我们的输入经过了模型,并得到了输出output

  • 之后计算输出和target之间的误差loss

  • 调用误差的反向传播loss.backwrd更新每个参数对应的梯度

  • 调用optimizer.step()对卷积核中的参数进行优化调整

  • 之后继续进入for循环,使用函数optimizer.zero_grad()对每个参数的梯度进行清零,防止上一轮循环中计算出来的梯度影响下一轮循环。

2. 优化器的使用

优化器中算法共有的参数(其他参数因优化器的算法而异):

  • params: 传入优化器模型中的参数

  • lr: learning rate,即学习速率

关于学习速率

  • 一般来说,学习速率设置得太大,模型运行起来会不稳定

  • 学习速率设置得太小,模型训练起来会过

  • 建议在最开始训练模型的时候,选择设置一个较大的学习速率;训练到后面的时候,再选择一个较小的学习速率

代码栗子:

  1. import torch.optim
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
  5. from torch.utils.data import DataLoader
  6. dataset=torchvision.datasets.CIFAR10("./dataset",train=False,download=True,transform=torchvision.transforms.ToTensor())
  7. dataloder=DataLoader(dataset,batch_size=1)
  8. class Demo(nn.Module):
  9. def __init__(self):
  10. super(Demo,self).__init__()
  11. self.model1=Sequential(
  12. Conv2d(3,32,5,padding=2),
  13. MaxPool2d(2),
  14. Conv2d(32, 32, 5, padding=2),
  15. MaxPool2d(2),
  16. Conv2d(32, 64, 5, padding=2),
  17. MaxPool2d(2),
  18. Flatten(),
  19. Linear(1024, 64),
  20. Linear(64, 10)
  21. )
  22. def forward(self,x):
  23. x=self.model1(x)
  24. return x
  25. demo=Demo()
  26. loss=nn.CrossEntropyLoss()
  27. #设置优化器
  28. #选择随机梯度下降
  29. optim=torch.optim.SGD(demo.parameters(),lr=0.01) #一般来说,学习速率设置得太大,模型运行起来会不稳定;设置得太小,模型训练起来会比较慢
  30. #对数据进行20次循环
  31. for epoch in range(20):
  32. running_loss=0.0 #初始化loss
  33. #该循环只对数据进行了一次训练
  34. for data in dataloder:
  35. imgs,targets=data
  36. output=demo(imgs)
  37. result_loss=loss(output,targets)
  38. #----------------优化器训练过程---------------------
  39. optim.zero_grad() #各个参数对应的梯度设置为0
  40. result_loss.backward() #反向传播,得到每个节点对应的梯度
  41. optim.step() #根据每个参数的梯度,对参数进行调优
  42. running_loss=running_loss+result_loss #累加该轮循环的loss,计算该轮循环整体误差的总和
  43. print(running_loss) #输出该轮循环整体误差的总和
  • [Run]

    tensor(18713.4336, grad_fn=)
    tensor(16178.3564, grad_fn=)
    tensor(15432.6172, grad_fn=)
    tensor(16043.1025, grad_fn=)
    tensor(18018.3359, grad_fn=)

    ......

总结使用优化器训练的训练套路):

  • 设置损失函数loss function

  • 定义优化器optim

  • 从使用循环dataloader中的数据:for data in dataloder

    • 取出图片imgs,标签targets:imgs,targets=data

    • 将图片放入神经网络,并得到一个输出:output=model(imgs)

    • 计算误差:loss_result=loss(output,targets)

    • 使用优化器,初始化参数的梯度为0:optim.zero_grad()

    • 使用反向传播求出梯度:loss_result.backward()

    • 根据梯度,对每一个参数进行更新:optim.step()

  • 进入下一个循环,直到完成训练所需的循环次数

3. 如何调整学习速率

再复制粘贴一次:

  • 一般来说,学习速率设置得太大,模型运行起来会不稳定

  • 学习速率设置得太小,模型训练起来会过

  • 建议在最开始训练模型的时候,选择设置一个较大的学习速率;训练到后面的时候,再选择一个较小的学习速率

pytorch中提供了一些方法,可以动态地调整学习速率

官方文档:StepLR — PyTorch 2.0 documentation

(1)StepLR参数简介

参数介绍:

  • optimizer: 放入模型所使用的优化器名称

  • step_size(int): 训练的时候,每多少步进行一个更新

  • gamma(float): 默认为0.1。在循环中,每次训练的时候,新的学习速率=原来学习速率×gamma

不同的优化器中有很多不同的参数,但是这些参数都是跟几个特定的算法相关的,这些需要使用的时候再去了解。

如果只是单纯地使用优化器,那么只需设置optimizer学习速率,就可以满足绝大部分的训练需求。

(2)StepLR代码栗子

  1. import torch.optim
  2. import torchvision
  3. from torch import nn
  4. from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
  5. from torch.utils.data import DataLoader
  6. dataset=torchvision.datasets.CIFAR10("./dataset",train=False,download=True,transform=torchvision.transforms.ToTensor())
  7. dataloder=DataLoader(dataset,batch_size=1)
  8. class Demo(nn.Module):
  9. def __init__(self):
  10. super(Demo,self).__init__()
  11. self.model1=Sequential(
  12. Conv2d(3,32,5,padding=2),
  13. MaxPool2d(2),
  14. Conv2d(32, 32, 5, padding=2),
  15. MaxPool2d(2),
  16. Conv2d(32, 64, 5, padding=2),
  17. MaxPool2d(2),
  18. Flatten(),
  19. Linear(1024, 64),
  20. Linear(64, 10)
  21. )
  22. def forward(self,x):
  23. x=self.model1(x)
  24. return x
  25. demo=Demo()
  26. loss=nn.CrossEntropyLoss()
  27. #设置优化器
  28. #选择随机梯度下降
  29. optim=torch.optim.SGD(demo.parameters(),lr=0.01) #一般来说,学习速率设置得太大,模型运行起来会不稳定;设置得太小,模型训练起来会比较慢
  30. #加入学习速率更新
  31. scheduler = torch.optim.lr_scheduler.StepLR(optim, step_size=5, gamma=0.1)
  32. #对数据进行20次循环
  33. for epoch in range(20):
  34. running_loss=0.0 #初始化loss
  35. #该循环只对数据进行了一次训练
  36. for data in dataloder:
  37. imgs,targets=data
  38. output=demo(imgs)
  39. result_loss=loss(output,targets)
  40. #----------------优化器训练过程---------------------
  41. optim.zero_grad() #各个参数对应的梯度设置为0;如果不写这行代码,那么每次循环中都会对这个梯度进行累加
  42. result_loss.backward() #反向传播,得到每个节点对应的梯度
  43. #optim.step() #根据每个参数的梯度,对参数进行调优
  44. scheduler.step() #对每个参数的学习速率进行调整;通过scheduler可以在每次循环中对学习速率进行下降
  45. running_loss=running_loss+result_loss #累加该轮循环的loss,计算该轮循环整体误差的总和
  46. print(running_loss) #输出该轮循环整体误差的总和

原文链接:https://www.cnblogs.com/zoubilin/p/17704380.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号