Взрывающийся градиент для gpflow SVGP
При оптимизации SVGP с вероятностью Пуассона для большого набора данных, я вижу то, что я считаю взрывающимися градиентами. После нескольких эпох я вижу колючее падение ELBO, которое затем очень медленно восстанавливается после избавления от всего достигнутого ранее прогресса. Примерно 21 итерация соответствует эпохе.
Этот всплеск (по крайней мере, второй) привел к полному смещению параметров (для векторов параметров я просто нанес норму, чтобы увидеть изменения):
Как я могу справиться с этим? Мой первый подход заключается в том, чтобы обрезать градиент, но, похоже, для этого нужно копаться в коде gpflow.
Моя настройка:
Обучение работает через естественные градиенты для вариационных параметров и ADAM для остальных, с медленно (линейно) возрастающим графиком для естественной градиентной гаммы.
Размеры партии и точки индукции являются максимально возможными для моей установки (оба 2^12, с набором данных, состоящим из ~88k выборок). Я включаю 1e-5 джиттер и инициализирую точки индукции с помощью kmeans.
Я использую комбинированное ядро, состоящее из комбинации RBF, Matern52, периодического и линейного ядра, в общей сложности 95 функций (многие из них из-за однократного кодирования), все они доступны для изучения. Шкалы длины преобразуются с помощью gpflow.transforms.
with gpflow.defer_build():
k1 = Matern52(input_dim=len(kernel_idxs["coords"]), active_dims=kernel_idxs["coords"], ARD=False)
k2 = Periodic(input_dim=len(kernel_idxs["wday"]), active_dims=kernel_idxs["wday"])
k3 = Linear(input_dim=len(kernel_idxs["onehot"]), active_dims=kernel_idxs["onehot"], ARD=True)
k4 = RBF(input_dim=len(kernel_idxs["rest"]), active_dims=kernel_idxs["rest"], ARD=True)
#
k1.lengthscales.transform = gpflow.transforms.Exp()
k2.lengthscales.transform = gpflow.transforms.Exp()
k3.variance.transform = gpflow.transforms.Exp()
k4.lengthscales.transform = gpflow.transforms.Exp()
m = gpflow.models.SVGP(X, Y, k1 + k2 + k3 + k4, gpflow.likelihoods.Poisson(), Z,
mean_function=gpflow.mean_functions.Constant(c=np.ones(1)),
minibatch_size=MB_SIZE, name=NAME)
m.mean_function.set_trainable(False)
m.compile()
ОБНОВЛЕНИЕ: использование только ADAM Следуя предложению Марка, я переключился только на ADAM, что помогло мне избавиться от этого внезапного взрыва. Тем не менее, я все еще инициализировался только с натградской эпохой, которая, кажется, экономит много времени.
Кроме того, вариационные параметры, кажется, изменяются гораздо менее резко (по крайней мере, с точки зрения их нормы). Я предполагаю, что они будут сходиться намного медленнее, но, по крайней мере, они стабильны
2 ответа
Это очень интересно Возможно, попытка не использовать natgrads - тоже хорошая идея. Обрезание градиентов действительно похоже на взлом, который может сработать. И да, для этого потребуется немного покопаться в коде GPflow. Один из советов, который может помочь в этом, - это не использовать оптимизаторы GPflow напрямую. model._likelihood_tensor
содержит тензор TF, который должен быть оптимизирован. Возможно, с помощью некоторой ручной магии TensorFlow, вы можете сделать отсечение градиента здесь перед запуском оптимизатора.
В общем, я думаю, это звучит так, как будто вы наткнулись на реальную проблему исследования. Обычно эти большие градиенты имеют вескую причину в модели, к которой можно обратиться с осторожной продуманностью. Разница в какой-то оценке Монте-Карло? Плохо ли работает целевая функция?
Относительно того, почему не помогает использование естественных градиентов. Естественные градиенты используют матрицу Фишера в качестве предварительного условия для выполнения оптимизации второго порядка. Это может привести к довольно агрессивным движениям в пространстве параметров. В некоторых случаях (когда имеются пригодные отношения сопряженности), эти агрессивные действия могут значительно ускорить оптимизацию. Этот случай, с вероятностью Пуассона, не является тем, где существуют отношения сопряженности, которые обязательно помогут оптимизации. Фактически, предварительный кондиционер Фишера часто может быть вредным, особенно когда вариационные параметры не близки к оптимальным.
Просто добавьте к ответу Марка, приведенному выше, при использовании nat grads в несопряженных моделях для достижения максимальной производительности может потребоваться некоторая настройка, и нестабильность может стать проблемой. Как указывает Марк, большие шаги, которые обеспечивают потенциально более быструю сходимость, могут также привести к тому, что параметры окажутся в плохих областях пространства параметров. Когда вариационная аппроксимация хороша (т. Е. Истинный и приблизительный апостериор близки), есть веские основания ожидать, что nat grad будет работать хорошо, но, к сожалению, в общем случае нет серебряной пули. Смотрите https://arxiv.org/abs/1903.02984 для некоторой интуиции.