深度学习训练过程中学习率的大小十分重要。学习率过低会导致学习太慢,学习率过高会导致难以收敛。通常情况下,初始学习率会比较大,后来逐渐缩小学习率。
首先定义两层全连接层模型
- import torch
- from torch import nn
- class Net(nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.layer1 = nn.Linear(10, 2)
- self.layer2 = nn.Linear(2, 10)
-
- def forward(self, input):
- return self.layer2(self.layer1(input))
神经网络的执行步骤。首先神经网络进过前向传播,这是神经网络框架会搭建好计算图(这里会保存操作和对应参与计算的张量,因为在根据计算图计算梯度时需要这些信息)。然后是误差反向传播,loss.backward() ,这时会计算梯度信息。最后根据梯度信息,更新参数。
- loss.backward()
- optimizer.step()
- optimizer.zero_grad()
optimizer.zero_grad() 是将这一轮的梯度清零,防止影响下一轮参数的更新。这里曾问过面试的问题:什么时候不使用这一步进行清零。
- model = Net()
- # 只传入想要训练层的参数。其他未传入的参数不参与更新
- optimizer_Adam = torch.optim.Adam(model.parameters(), lr=0.1)
model.parameters()会返回模型的所有参数
也就是说只传入模型待优化的参数,为传入的参数不参与更新。
- model = Net()
- # 只传入待优化的参数
- optimizer_Adam = torch.optim.Adam(model.layer1.parameters(), lr=0.1)
- params_dict = [{'params': model.layer1.parameters(), 'lr': 0.01},
- {'params': model.layer2.parameters(), 'lr': 0.001}]
- optimizer = torch.optim.Adam(params_dict)
- -param_groups
- -0(dict) # 第一组参数
- params: # 维护要更新的参数
- lr: # 该组参数的学习率
- betas:
- eps: # 该组参数的学习率最小值
- weight_decay: # 该组参数的权重衰减系数
- amsgrad:
- -1(dict) # 第二组参数
- -2(dict) # 第三组参数
parm_group是一个列表,其中每个元素都是一个字典
- model = Net() # 生成网络
- optimizer = torch.optim.Adam(model.parameters(), lr=0.1) # 生成优化器
-
- for epoch in range(100): # 假设迭代100个epoch
- if epoch % 5 == 0: # 每迭代5次,更新一次学习率
- for params in optimizer.param_groups:
- # 遍历Optimizer中的每一组参数,将该组参数的学习率 * 0.9
- params['lr'] *= 0.9