RMSProp¶
Описание¶
RMSProp (root mean square propagation) - это алгоритм оптимизации, разработанный параллельно с AdaDelta и являющийся его составляющей. Оба алгоритма были созданы для решения основной проблемы AdaGrad: бесконтрольного накопления квадратов градиентов, которое в конечном итоге приводило к параличу процесса обучения.
Идея RMSProp следующая: вместо полной суммы обновлений G_t будет использоваться усреднённый по истории квадрат градиента. Метод напоминает принцип, используемый в MomentumSGD - метод экспоненциально затухающего бегущего среднего.
Введём обозначение E[g^2]_t - бегущее среднее квадрата градиента в момент времени t. Формула для его вычисления следующая:
Тогда, подставив E[g^2]_t в формулу обновления параметров для AdaGrad вместо G_t, получим (матричные операции опущены для упрощения):
Знаменатель - корень из среднего квадратов градиентов, т.е. root mean square, RMS:
Рекомендуемыми значениями являются \eta = 0.001 и \gamma = 0.9.
Инициализация¶
def __init__(self, learnRate=1e-3, factor=0.1, epsilon=1e-5, nodeinfo=None):
Параметры
Параметр | Возможные типы | Описание | По умолчанию |
---|---|---|---|
learnRate | float | Скорость обучения | 1e-3 |
factor | float | Коэффициент сохранения | 0.1 |
epsilon | float | Сглаживающий параметр | 1e-5 |
nodeinfo | NodeInfo | Объект, содержащий информацию о вычислительном узле | None |
Пояснения
-
Примеры¶
Необходимые импорты:
import numpy as np
from PuzzleLib.Optimizers import RMSProp
from PuzzleLib.Backend import gpuarray
Info
gpuarray
необходим для правильного размещения тензора на GPU.
Создадим синтетическую обучающую выборку:
data = gpuarray.to_gpu(np.random.randn(16, 128).astype(np.float32))
target = gpuarray.to_gpu(np.random.randn(16, 1).astype(np.float32))
Объявляем оптимизатор:
optimizer = RMSProp(learnRate=0.001, factor=0.9)
Пусть уже есть некоторая сеть net
, определённая, например, через Graph, тогда, чтобы установить оптимизатор на сеть, требуется следующее:
optimizer.setupOn(net, useGlobalState=True)
Info
Подробнее про методы оптимизаторов и их параметры читайте в описании родительского класса Optimizer
Также пусть есть некая функция ошибки loss
, наследованная от Cost, рассчитывающая в т.ч. её градиент. Тогда получаем реализацию процесса оптимизации:
for i in range(100):
... predictions = net(data)
... error, grad = loss(predictions, target)
... optimizer.zeroGradParams()
... net.backward(grad)
... optimizer.update()
... if (i + 1) % 5 == 0:
... print("Iteration #%d error: %s" % (i + 1, error))