Класс RAdam
Класс RAdam реализует оптимизатор Rectified Adam (RAdam),
предложенный в 2019 году. Этот алгоритм является модификацией классического
Adam и решает проблему нестабильности на ранних этапах обучения.
Основная идея RAdam заключается в использовании выпрямления (rectification)
для автоматического управления скоростью обучения, что позволяет
избежать резких скачков градиента в начале обучения.
В отличие от стандартного Adam, RAdam не требует дополнительной
настройки параметра betas для стабилизации начальной фазы.
Синтаксис
torch.optim.RAdam(
params,
lr=0.001,
betas=(0.9, 0.999),
eps=1e-8,
weight_decay=0
)
Основные параметры конструктора:
-
params- итерируемый объект с параметрами модели или словарями, определяющими группы параметров -
lr- скорость обучения (по умолчанию 0.001) -
betas- коэффициенты для вычисления скользящего среднего градиента и квадрата градиента (по умолчанию (0.9, 0.999)) -
eps- небольшое значение для численной стабильности (по умолчанию 1e-8) -
weight_decay- коэффициент регуляризации L2 (по умолчанию 0)
Пример с обучением линейной модели
Рассмотрим базовый пример использования оптимизатора RAdam для обучения линейной регрессии:
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
torch.manual_seed(0)
X = torch.randn(100, 5)
y = torch.randn(100, 1)
model = nn.Linear(5, 1)
optimizer = torch.optim.RAdam(model.parameters(), lr=0.01)
criterion = nn.MSELoss()
dataset = TensorDataset(X, y)
loader = DataLoader(dataset, batch_size=16)
for epoch in range(3):
total_loss = 0
for batch_X, batch_y in loader:
optimizer.zero_grad()
output = model(batch_X)
loss = criterion(output, batch_y)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f'Epoch {epoch+1}: loss = {total_loss/len(loader):.4f}')
Результат выполнения кода:
Epoch 1: loss = 1.5713
Epoch 2: loss = 1.5673
Epoch 3: loss = 1.5634
Пример с разными скоростями обучения для слоёв
RAdam позволяет задавать разные параметры для различных групп параметров модели. В этом примере для первого слоя установлена скорость обучения 0.01, а для второго - 0.001:
import torch
import torch.nn as nn
torch.manual_seed(0)
class SimpleNet(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(10, 20)
self.fc2 = nn.Linear(20, 5)
def forward(self, x):
x = torch.relu(self.fc1(x))
return self.fc2(x)
model = SimpleNet()
optimizer = torch.optim.RAdam([
{'params': model.fc1.parameters(), 'lr': 0.01},
{'params': model.fc2.parameters(), 'lr': 0.001}
])
print('Optimizer parameter groups:')
for i, group in enumerate(optimizer.param_groups):
print(f'Group {i+1}: lr = {group["lr"]}')
Результат выполнения кода:
Optimizer parameter groups:
Group 1: lr = 0.01
Group 2: lr = 0.001
Сравнение с Adam
На практике RAdam часто показывает более стабильную сходимость
на ранних этапах обучения, особенно для глубоких моделей
и при работе с большими батчами. Стандартный Adam
в начале обучения может иметь слишком высокую дисперсию
градиентов, что приводит к неустойчивому поведению.
RAdam автоматически корректирует этот эффект, используя
выпрямление, которое уменьшает скорость обучения в начале
и постепенно увеличивает её по мере накопления статистики:
import torch
import torch.nn as nn
torch.manual_seed(0)
model = nn.Linear(10, 1)
optimizer_adam = torch.optim.Adam(model.parameters(), lr=0.001)
optimizer_radam = torch.optim.RAdam(model.parameters(), lr=0.001)
print('Using RAdam with rectification')
print('Adam uses momentum, RAdam uses rectified momentum')