PyTorch框架学习十三——优化器
- 一、优化器
- 二、Optimizer类
- 1.基本属性
- 2.基本方法
- 三、学习率与动量
- 1.学习率learning rate
- 2.动量、冲量Momentum
- 四、十种常见的优化器(简单罗列)
上次笔记简单介绍了一下损失函数的概念以及18种常用的损失函数,这次笔记介绍优化器的相关知识以及PyTorch中的使用。
一、优化器
PyTorch中的优化器:管理并更新模型中可学习参数的值,使得模型输出更接近真实标签。
导数:函数在指定坐标轴上的变化率。
方向导数:指定方向上的变化率。
梯度:一个向量,方向为方向导数取得最大值的方向。
二、Optimizer类
1.基本属性
- defaults:优化器超参数,包含优化选项的默认值的dict(当参数组没有指定这些值时使用)。
- state:参数的缓存,如momentum的缓存。
- param_groups:管理的参数组,形式上是列表,每个元素都是一个字典。
2.基本方法
(1)zero_grad():清空所管理的参数的梯度。因为PyTorch中张量梯度不会自动清零。
weight = torch.randn((2, 2), requires_grad=True)
weight.grad = torch.ones((2, 2))optimizer = optim.SGD([weight], lr=0.1)print("weight before step:{}".format(weight.data))
optimizer.step() # 修改lr=1 0.1观察结果
print("weight after step:{}".format(weight.data))print("weight in optimizer:{}\nweight in weight:{}\n".format(id(optimizer.param_groups[0]['params'][0]), id(weight)))print("weight.grad is {}\n".format(weight.grad))
optimizer.zero_grad()
print("after optimizer.zero_grad(), weight.grad is\n{}".format(weight.grad))
结果如下:
weight before step:tensor([[0.6614, 0.2669],[0.0617, 0.6213]])
weight after step:tensor([[ 0.5614, 0.1669],[-0.0383, 0.5213]])
weight in optimizer:1314236528344
weight in weight:1314236528344weight.grad is tensor([[1., 1.],[1., 1.]])after optimizer.zero_grad(), weight.grad is
tensor([[0., 0.],[0., 0.]])
(2) step():执行一步优化更新。
weight = torch.randn((2, 2), requires_grad=True)
weight.grad = torch.ones((2, 2))optimizer = optim.SGD([weight], lr=0.1)print("weight before step:{}".format(weight.data))
optimizer.step() # 修改lr=1 0.1观察结果
print("weight after step:{}".format(weight.data))
结果如下:
weight before step:tensor([[0.6614, 0.2669],[0.0617, 0.6213]])
weight after step:tensor([[ 0.5614, 0.1669],[-0.0383, 0.5213]])
(3) add_param_group():添加参数组。
weight = torch.randn((2, 2), requires_grad=True)
weight.grad = torch.ones((2, 2))optimizer = optim.SGD([weight], lr=0.1)print("optimizer.param_groups is\n{}".format(optimizer.param_groups))w2 = torch.randn((3, 3), requires_grad=True)optimizer.add_param_group({"params": w2, 'lr': 0.0001})print("optimizer.param_groups is\n{}".format(optimizer.param_groups))
结果如下:
optimizer.param_groups is
[{'params': [tensor([[0.6614, 0.2669],[0.0617, 0.6213]], requires_grad=True)], 'lr': 0.1, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}]
optimizer.param_groups is
[{'params': [tensor([[0.6614, 0.2669],[0.0617, 0.6213]], requires_grad=True)], 'lr': 0.1, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}, {'params': [tensor([[-0.4519, -0.1661, -1.5228],[ 0.3817, -1.0276, -0.5631],[-0.8923, -0.0583, -0.1955]], requires_grad=True)], 'lr': 0.0001, 'momentum': 0, 'dampening': 0, 'weight_decay': 0, 'nesterov': False}]
(4)state_dict():获取优化器当前状态信息字典。
weight = torch.randn((2, 2), requires_grad=True)
weight.grad = torch.ones((2, 2))optimizer = optim.SGD([weight], lr=0.1, momentum=0.9)
opt_state_dict = optimizer.state_dict()print("state_dict before step:\n", opt_state_dict)for i in range(10):optimizer.step()print("state_dict after step:\n", optimizer.state_dict())torch.save(optimizer.state_dict(), os.path.join(BASE_DIR, "optimizer_state_dict.pkl"))
结果如下:
state_dict before step:{'state': {}, 'param_groups': [{'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [2872948098296]}]}
state_dict after step:{'state': {2872948098296: {'momentum_buffer': tensor([[6.5132, 6.5132],[6.5132, 6.5132]])}}, 'param_groups': [{'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [2872948098296]}]}
获取到了优化器当前状态的信息字典,其中那个2872948098296是存放权重的地址,并将这些参数信息保存为一个pkl文件:
(5)load_state_dict():加载状态信息字典。
optimizer = optim.SGD([weight], lr=0.1, momentum=0.9)
state_dict = torch.load(os.path.join(BASE_DIR, "optimizer_state_dict.pkl"))print("state_dict before load state:\n", optimizer.state_dict())
optimizer.load_state_dict(state_dict)
print("state_dict after load state:\n", optimizer.state_dict())
从刚刚保存参数的pkl文件中读取参数赋给一个新的空的优化器,结果为:
state_dict before load state:{'state': {}, 'param_groups': [{'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [1838346925624]}]}
state_dict after load state:{'state': {1838346925624: {'momentum_buffer': tensor([[6.5132, 6.5132],[6.5132, 6.5132]])}}, 'param_groups': [{'lr': 0.1, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [1838346925624]}]}
注:state_dict()与load_state_dict()一般经常用于模型训练中的保存和读取模型参数,防止断电等突发情况导致模型训练强行中断而前功尽弃。
三、学习率与动量
1.学习率learning rate
梯度下降:
其中LR就是学习率,作用是控制更新的步伐,如果太大可能导致模型无法收敛或者是梯度爆炸,如果太小可能使得训练时间过长,需要调节。
2.动量、冲量Momentum
结合当前梯度与上一次更新信息,用于当前更新。
PyTorch中梯度下降的更新公式为:
其中:
- Wi:第i次更新的参数。
- lr:学习率。
- Vi:更新量。
- m:momentum系数。
- g(Wi):Wi的梯度。
举个例子:
100这个时刻的更新量不仅与当前梯度有关,还与之前的梯度有关,只是越以前的对当前时刻的影响就越小。
momentum的作用主要是可以加速收敛。
四、十种常见的优化器(简单罗列)
目前对优化器的了解还不多,以后会继续跟进,这里就简单罗列一下:
- optim.SGD:随机梯度下降法
- optim.Adagrad:自适应学习率梯度下降法
- optim.RMSprop:Adagrad的改进
- optim.Adadelta:Adagrad的改进
- optim.Adam:RMSprop结合Momentum
- optim.Adamax:Adam增加学习率上限
- optim.SparseAdam:稀疏版的Adam
- optim.ASGD:随机平均梯度下降法
- optim.Rprop:弹性反向传播
- optim.LBFGS :BFGS的改进