训练中动态调整学习率lr,optimizer.param_groups

本文详细介绍了在深度学习训练过程中如何动态调整学习率的方法。包括通过新建optimizer或直接修改optimizer.param_groups来实现学习率的调整,以及动态修改学习率的具体代码示例。文章还探讨了不同方法对模型收敛的影响。

四、在训练中动态的调整学习率

 

1

2

3

4

5

6

7

8

9

'''调整学习率'''

# 新建optimizer或者修改optimizer.params_groups对应的学习率

# # 新建optimizer更简单也更推荐,optimizer十分轻量级,所以开销很小

# # 但是新的优化器会初始化动量等状态信息,这对于使用动量的优化器(momentum参数的sgd)可能会造成收敛中的震荡

# ## optimizer.param_groups:长度2的list,optimizer.param_groups[0]:长度6的字典

print(optimizer.param_groups[0]['lr'])

old_lr = 0.1

optimizer = optim.SGD([{'params': net.features.parameters()},

                       {'params': net.classifiter.parameters(), 'lr': old_lr*0.1}], lr=1e-5)

 可以看到optimizer.param_groups结构,[{'params','lr', 'momentum', 'dampening', 'weight_decay', 'nesterov'},{……}],集合了优化器的各项参数。

 

--------------------------------------------------------------------

动态修改学习率
for param_group in optimizer.param_groups:
    param_group["lr"] = lr 


得到学习率   optimizer.param_groups[0]["lr"] 

我自己查看的优化器参数

# print('查看optimizer.param_groups结构:')
# i_list=[i for i in optimizer.param_groups[0].keys()]
# print(i_list)    
['amsgrad', 'params', 'lr', 'betas', 'weight_decay', 'eps']

 

参考链接:

https://www.cnblogs.com/hellcat/p/8496727.html

https://www.pytorchtutorial.com/pytorch-learning-rate-decay/   

<think>我们正在讨论PyTorch中的优化器参数组(optimizer.param_groups)。用户询问的是在param_groups中`initial_lr`和`lr`的区别。 根据引用[2]中的代码片段: if optimizer is not None and self.max_iters - self.iter <= 1: for group in self.optimizer.param_groups: group['initial_lr'] = group['lr'] 这段代码在特定条件下(当迭代次数接近最大迭代次数时)将当前学习率lr)赋值给initial_lr。 另外,引用[1]和[3]描述了param_groups的结构,但都没有直接提到`initial_lr`。标准情况下,当我们创建一个优化器时,参数组中通常包含的是当前学习率lr),以及其他超参数如动量、权重衰减等。而`initial_lr`并不是优化器默认创建的字段。 因此,我们可以推断: - `lr`:是优化器参数组中的标准字段,表示当前的学习率。在训练过程中,学习率调度器(scheduler)会动态调整这个值。 - `initial_lr`:通常不是优化器初始化时自带的字段,而是在使用学习率调度器时由调度器设置的一个字段。它记录了参数组的初始学习率(即优化器创建时的学习率),以便在调度器中使用(例如,在余弦退火等调度策略中需要知道初始学习率)。 在PyTorch的学习率调度器中,例如`LambdaLR`、`CosineAnnealingLR`等,在初始化调度器时,调度器会遍历优化器的每个参数组,并将当前参数组的`lr`值保存为`initial_lr`(作为一个额外的字段添加到参数组字典中)。这样,在调度器的每一步更新中,就可以根据初始学习率来计算新的学习率。 例如,查看PyTorch的`LambdaLR`源码(https://pytorch.org/docs/stable/_modules/torch/optim/lr_scheduler.html#LambdaLR): class LambdaLR(LRScheduler): def __init__(self, optimizer, lr_lambda, last_epoch=-1, verbose=False): ... super(LambdaLR, self).__init__(optimizer, last_epoch, verbose) # 在基类LRScheduler的__init__中,会执行以下操作: # for group in optimizer.param_groups: # group.setdefault('initial_lr', group['lr']) # 即如果参数组中没有'initial_lr',则用当前的'lr'作为初始学习率。 所以,区别总结如下: - `lr`:当前学习率,随着训练过程动态变化。 - `initial_lr`:初始学习率,通常由学习率调度器在初始化时设置,并在整个训练过程中保持不变(除非人为修改)。 需要注意的是,如果没有使用学习率调度器,那么参数组中可能没有`initial_lr`这个字段。因此,在引用[2]的代码中,作者在特定条件下手动设置`initial_lr`,可能是为了在后续的调度中使用。 如果用户需要在自己的代码中使用`initial_lr`,建议通过调度器来设置,而不是手动添加(除非有特殊需求)。在创建调度器后,调度器会自动为每个参数组添加`initial_lr`字段。 下面是一个简单的例子说明: ```python import torch import torch.optim as optim from torch.optim import lr_scheduler model = torch.nn.Linear(10, 1) optimizer = optim.SGD(model.parameters(), lr=0.1) # 在创建调度器之前,参数组只有'lr',没有'initial_lr' print("Before scheduler initialization:") for group in optimizer.param_groups: print(group.keys()) # 输出:dict_keys(['params', 'lr', 'momentum', 'dampening', 'weight_decay', 'nesterov']) # 注意:这里没有'initial_lr' # 创建一个调度器(以StepLR为例) scheduler = lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) # 创建调度器后,调度器的初始化会为每个参数组设置'initial_lr'(使用当前的lr值) print("\nAfter scheduler initialization:") for group in optimizer.param_groups: print(group.keys()) # 现在应该包含'initial_lr' print(f"initial_lr: {group['initial_lr']}, lr: {group['lr']}") # initial_lr=0.1, lr=0.1 # 进行一步训练,然后更新学习率 optimizer.step() scheduler.step() # 假设更新后学习率变化(StepLR是在每个step_size周期后乘以gamma,但第一步通常不变) print("\nAfter one step:") for group in optimizer.param_groups: print(f"initial_lr: {group['initial_lr']}, lr: {group['lr']}") # initial_lr还是0.1,lr还是0.1(因为第一步未到step_size) # 假设我们进行了30步,然后再次调用scheduler.step() # 此时学习率会变为0.1 * 0.1 = 0.01 # 但initial_lr仍然是0.1 ``` 因此,结论是: - `initial_lr`是由学习率调度器设置并维护的初始学习率,用于调度计算。 - `lr`是当前的学习率,在训练过程中会被优化器和调度器更新。 如果用户没有使用调度器,那么参数组中就不会有`initial_lr`(除非像引用[2]中那样手动设置)。 相关问题: 1. 在PyTorch中,如何手动为优化器参数组添加`initial_lr`字段? 2. 学习率调度器如何影响优化器的学习率? 3. 在自定义学习率调度器时,是否需要设置`initial_lr`? </think>在 PyTorch 的优化器参数组 (`optimizer.param_groups`) 中,`initial_lr` 和 `lr` 是两个相关但有区别的重要参数: ### 1. **`lr` (当前学习率)** - **定义**:表示优化器当前正在使用的实际学习率值 - **动态变化**: - 在训练过程中会被学习率调度器 (`scheduler`) 动态调整 - 例如使用 `scheduler.step()` 后会更新此值[^2] - **初始化**:创建优化器时由用户显式设置 ```python optimizer = torch.optim.SGD(model.parameters(), lr=0.1) # 初始设置lr=0.1 ``` - **访问方式**: ```python current_lr = optimizer.param_groups[0]['lr'] ``` ### 2. **`initial_lr` (初始学习率)** - **定义**:记录优化器创建时设置的原始学习率值 - **静态特性**: - 通常不会在训练过程中自动改变 - 需要手动设置才会出现在参数组中[^2] ```python # 手动设置initial_lr (通常在特定条件下) if condition: for group in optimizer.param_groups: group['initial_lr'] = group['lr'] # 将当前lr保存为initial_lr[^2] ``` - **用途**: - 作为学习率调度器的基准参考值 - 实现自定义学习率策略时作为复位锚点 - 在模型热重启(warm restart)等场景中使用 ### 关键区别总结 | 特性 | `lr` (当前学习率) | `initial_lr` (初始学习率) | |--------------|---------------------------|-----------------------------| | **是否自动存在** | 总是存在 ✓ | 需手动设置 ✗ | | **可变性** | 动态变化 (被scheduler修改) | 通常静态不变 | | **初始化** | 用户创建优化器时设置 | 需显式赋值(常取初始lr值) | | **典型用途** | 控制当前优化步长 | 作为学习率调整的基准参考 | ### 使用示例 ```python # 创建优化器 (自动设置lr) optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # 手动记录初始学习率 for group in optimizer.param_groups: group['initial_lr'] = group['lr'] # 保存初始值[^2] # 训练... scheduler.step() # 更新学习率 # 查看对比 print(f"初始学习率: {optimizer.param_groups[0]['initial_lr']}") # 0.01 print(f"当前学习率: {optimizer.param_groups[0]['lr']}") # 可能已改变 ``` ### 注意事项 1. `initial_lr` 不是 PyTorch 优化器的默认字段,需要显式创建[^2] 2. 学习率调度器内部会自动维护初始学习率副本,但不会直接写入 `param_groups` 3. 在自定义训练循环中,手动维护 `initial_lr` 有助于实现复杂的学习率策略
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值