在 PyTorch 中,你可以通过为优化器传递不同的学习率来针对不同的可调参数分配不同的学习率。这通常通过向优化器传递一个字典列表来实现,其中每个字典指定特定参数组的学习率。下面是一个示例代码,展示了如何实现这一点:
import torch
import torch.optim as optim
# 假设我们有两个模型参数:param1 和 param2
param1 = torch.nn.Parameter(torch.randn(2, 3))
param2 = torch.nn.Parameter(torch.randn(3, 4))
# 将这些参数分配给不同的学习率
optimizer = optim.SGD([
{'params': param1, 'lr': 0.01},
{'params': param2, 'lr': 0.001}
], lr=0.01, momentum=0.9)
# 模拟一次训练步骤
loss = (param1.sum() + param2.sum()) ** 2
loss.backward()
optimizer.step()
# 打印更新后的参数值
print(param1)
print(param2)
对于余弦退火算法中,对于可调的学习率,pytorch对不同的可调参数,分配不同的学习率权重
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR
# 假设我们有两个模型参数:param1 和 param2
param1 = torch.nn.Parameter(torch.randn(2, 3))
param2 = torch.nn.Parameter(torch.randn(3, 4))
# 为每个参数组分配不同的学习率
optimizer = optim.SGD([
{'params': param1, 'lr': 0.01},
{'params': param2, 'lr': 0.001}
], lr=0.01, momentum=0.9)
# 为整个优化器设置余弦退火调度器
scheduler = CosineAnnealingLR(optimizer, T_max=10, eta_min=0.0001)
# 模拟一个训练周期
for epoch in range(10):
# 执行优化步骤
loss = (param1.sum() + param2.sum()) ** 2
loss.backward()
optimizer.step()
# 更新学习率
scheduler.step()
# 打印当前学习率
for i, param_group in enumerate(optimizer.param_groups):
print(f'Epoch {epoch+1}, Param Group {i+1}: Learning Rate = {param_group["lr"]}')
两个参数先后优化,第一阶段主要优化param1,后一阶段主要优化param2
方法1:分阶段调整优化器的参数组
你可以在第一阶段只优化 param1,然后在第二阶段只优化 param2。这可以通过在不同阶段将 param1 或 param2 从优化器中移除或冻结(将学习率设置为 0)来实现。
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR
# 假设我们有两个模型参数:param1 和 param2
param1 = torch.nn.Parameter(torch.randn(2, 3))
param2 = torch.nn.Parameter(torch.randn(3, 4))
# 第一阶段:仅优化 param1
optimizer1 = optim.SGD([{'params': param1, 'lr': 0.01}], momentum=0.9)
scheduler1 = CosineAnnealingLR(optimizer1, T_max=5, eta_min=0.0001)
# 第二阶段:仅优化 param2
optimizer2 = optim.SGD([{'params': param2, 'lr': 0.001}], momentum=0.9)
scheduler2 = CosineAnnealingLR(optimizer2, T_max=5, eta_min=0.0001)
# 模拟训练
for epoch in range(10):
# 第一阶段:前5个epoch优化param1
if epoch < 5:
optimizer1.zero_grad()
loss = (param1.sum()) ** 2
loss.backward()
optimizer1.step()
scheduler1.step()
print(f'Epoch {epoch+1}: Optimizing param1, LR = {scheduler1.get_last_lr()}')
# 第二阶段:后5个epoch优化param2
else:
optimizer2.zero_grad()
loss = (param2.sum()) ** 2
loss.backward()
optimizer2.step()
scheduler2.step()
print(f'Epoch {epoch+1}: Optimizing param2, LR = {scheduler2.get_last_lr()}')
方法2:同时设置不同的学习率,但不同阶段侧重不同的参数
在这个方法中,你可以在第一阶段为 param1 设置较大的学习率,param2 设置为非常小的学习率(几乎不变)。然后在第二阶段反过来。
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR
# 假设我们有两个模型参数:param1 和 param2
param1 = torch.nn.Parameter(torch.randn(2, 3))
param2 = torch.nn.Parameter(torch.randn(3, 4))
# 同时优化param1和param2,但不同阶段有不同的学习率
optimizer = optim.SGD([
{'params': param1, 'lr': 0.01}, # param1初始学习率较大
{'params': param2, 'lr': 0.0001} # param2初始学习率较小
], momentum=0.9)
scheduler = CosineAnnealingLR(optimizer, T_max=10, eta_min=0.00001)
# 模拟训练
for epoch in range(10):
optimizer.zero_grad()
# 计算损失
loss = (param1.sum() + param2.sum()) ** 2
loss.backward()
optimizer.step()
scheduler.step()
# 不同阶段调整学习率
if epoch == 5:
optimizer.param_groups[0]['lr'] = 0.0001 # param1 学习率降低
optimizer.param_groups[1]['lr'] = 0.01 # param2 学习率增大
# 打印学习率
print(f'Epoch {epoch+1}: LR for param1 = {optimizer.param_groups[0]["lr"]}, LR for param2 = {optimizer.param_groups[1]["lr"]}')