深度学习中的优化器有哪些特点?

摘要:反向传播可以求出神经网路中每个需要调节参数的梯度,优化器可以根据梯度进行调整,达到降低整体误差的作用。本节我们对优化器进行介绍。
反向传播可以求出神经网路中每个需要调节参数的梯度(grad),优化器可以根据梯度进行调整,达到降低整体误差的作用。下面我们对优化器进行介绍。 1. 如何使用优化器 官方文档:torch.optim — PyTorch 2.0 documentation (1)构造优化器 举个栗子: optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9) optimizer = optim.Adam([var1, var2], lr=0.0001) 首先选择优化器的算法optim.SGD 之后在优化器中放入模型参数model.parameters(),这一步是必备的 还可在函数中设置一些参数,如学习速率lr=0.01(这是每个优化器中几乎都会有的参数) (2)调用优化器中的step方法 step()方法就是利用我们之前获得的梯度,对神经网络中的参数进行更新。 举个栗子: for input, target in dataset: optimizer.zero_grad() output = model(input) loss = loss_fn(output, target) loss.backward() optimizer.step() 步骤optimizer.zero_grad()是必选的 我们的输入经过了模型,并得到了输出output 之后计算输出和target之间的误差loss 调用误差的反向传播loss.backwrd,更新每个参数对应的梯度。 调用optimizer.step()对卷积核中的参数进行优化调整。 之后继续进入for循环,使用函数optimizer.zero_grad()对每个参数的梯度进行清零,防止上一轮循环中计算出来的梯度影响下一轮循环。 2. 优化器的使用 优化器中算法共有的参数(其他参数因优化器的算法而异): params: 传入优化器模型中的参数 lr: learning rate,即学习速率 关于学习速率: 一般来说,学习速率设置得太大,模型运行起来会不稳定 学习速率设置得太小,模型训练起来会过慢 建议在最开始训练模型的时候,选择设置一个较大的学习速率;训练到后面的时候,再选择一个较小的学习速率 代码栗子: import torch.optim import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader dataset=torchvision.datasets.CIFAR10("./dataset",train=False,download=True,transform=torchvision.transforms.ToTensor()) dataloder=DataLoader(dataset,batch_size=1) class Demo(nn.Module): def __init__(self): super(Demo,self).__init__() self.model1=Sequential( Conv2d(3,32,5,padding=2), MaxPool2d(2), Conv2d(32, 32, 5, padding=2), MaxPool2d(2), Conv2d(32, 64, 5, padding=2), MaxPool2d(2), Flatten(), Linear(1024, 64), Linear(64, 10) ) def forward(self,x): x=self.model1(x) return x demo=Demo() loss=nn.CrossEntropyLoss() #设置优化器 #选择随机梯度下降 optim=torch.optim.SGD(demo.parameters(),lr=0.01) #一般来说,学习速率设置得太大,模型运行起来会不稳定;设置得太小,模型训练起来会比较慢 #对数据进行20次循环 for epoch in range(20): running_loss=0.0 #初始化loss #该循环只对数据进行了一次训练 for data in dataloder: imgs,targets=data output=demo(imgs) result_loss=loss(output,targets) #----------------优化器训练过程--------------------- optim.zero_grad() #各个参数对应的梯度设置为0 result_loss.backward() #反向传播,得到每个节点对应的梯度 optim.step() #根据每个参数的梯度,对参数进行调优 running_loss=running_loss+result_loss #累加该轮循环的loss,计算该轮循环整体误差的总和 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代码栗子 import torch.optim import torchvision from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential from torch.utils.data import DataLoader dataset=torchvision.datasets.CIFAR10("./dataset",train=False,download=True,transform=torchvision.transforms.ToTensor()) dataloder=DataLoader(dataset,batch_size=1) class Demo(nn.Module): def __init__(self): super(Demo,self).__init__() self.model1=Sequential( Conv2d(3,32,5,padding=2), MaxPool2d(2), Conv2d(32, 32, 5, padding=2), MaxPool2d(2), Conv2d(32, 64, 5, padding=2), MaxPool2d(2), Flatten(), Linear(1024, 64), Linear(64, 10) ) def forward(self,x): x=self.model1(x) return x demo=Demo() loss=nn.CrossEntropyLoss() #设置优化器 #选择随机梯度下降 optim=torch.optim.SGD(demo.parameters(),lr=0.01) #一般来说,学习速率设置得太大,模型运行起来会不稳定;设置得太小,模型训练起来会比较慢 #加入学习速率更新 scheduler = torch.optim.lr_scheduler.StepLR(optim, step_size=5, gamma=0.1) #对数据进行20次循环 for epoch in range(20): running_loss=0.0 #初始化loss #该循环只对数据进行了一次训练 for data in dataloder: imgs,targets=data output=demo(imgs) result_loss=loss(output,targets) #----------------优化器训练过程--------------------- optim.zero_grad() #各个参数对应的梯度设置为0;如果不写这行代码,那么每次循环中都会对这个梯度进行累加 result_loss.backward() #反向传播,得到每个节点对应的梯度 #optim.step() #根据每个参数的梯度,对参数进行调优 scheduler.step() #对每个参数的学习速率进行调整;通过scheduler可以在每次循环中对学习速率进行下降 running_loss=running_loss+result_loss #累加该轮循环的loss,计算该轮循环整体误差的总和 print(running_loss) #输出该轮循环整体误差的总和