Взрывающийся градиент для gpflow SVGP - PullRequest
0 голосов
/ 21 мая 2019

При оптимизации SVGP с вероятностью Пуассона для большого набора данных я вижу то, что я считаю взрывающимися градиентами.После нескольких эпох я вижу колючее падение ELBO, которое затем очень медленно восстанавливается после избавления от всего достигнутого ранее прогресса.Примерно 21 итерация соответствует эпохе.

ELBO

Этот всплеск (по крайней мере, второй) привел к полному сдвигу параметров (для векторов параметров я только что построил нормучтобы увидеть изменения): Parameters

Как с этим справиться?Мой первый подход заключается в том, чтобы обрезать градиент, но, похоже, для этого нужно копаться в коде gpflow.

Моя настройка:

Обучение работает с помощью естественных градиентов для вариационногопараметры и ADAM для остальных, с медленно (линейно) возрастающим графиком для естественной градиентной гаммы.

Размеры партии и точки индукции являются максимально возможными для моей установки (оба 2 ^ 12, с данныминабор, состоящий из ~ 88 тыс. образцов).Я включаю джиттер 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, что помогло мне избавиться от этого внезапного взрыва,Тем не менее, я все еще инициализировался только с натградской эпохой, которая, кажется, экономит много времени.

Comparison of ADAM+NATGRAD(grey) vs ADAM only(red)

Кроме того, вариационные параметры меняются гораздо менее резко (с точки зрения их нормы как минимум).Я предполагаю, что они будут сходиться намного медленнее, но, по крайней мере, они стабильны.Comparison of ADAM+NATGRAD(grey) vs ADAM only(red)

Ответы [ 2 ]

2 голосов
/ 22 мая 2019

Просто добавьте к ответу Марка, приведенному выше, при использовании градаций nat в несопряженных моделях для достижения наилучшей производительности может потребоваться некоторая настройка, и нестабильность может стать проблемой.Как отмечает Марк, большие шаги, которые обеспечивают потенциально более быструю сходимость, могут также привести к тому, что параметры окажутся в плохих областях пространства параметров.Когда вариационная аппроксимация хороша (т. Е. Истинный и приблизительный апостериор близки), есть веские основания ожидать, что nat grad будет работать хорошо, но, к сожалению, в общем случае нет серебряной пули.См. https://arxiv.org/abs/1903.02984 для некоторой интуиции.

1 голос
/ 21 мая 2019

Это очень интересно. Возможно, попытка не использовать natgrads - тоже хорошая идея. Обрезание градиентов действительно похоже на взлом, который может сработать. И да, для этого потребуется немного покопаться в коде GPflow. Один из советов, который может помочь в этом, - это не использовать оптимизаторы GPflow напрямую. model._likelihood_tensor содержит тензор TF, который должен быть оптимизирован. Возможно, с помощью некоторой ручной магии TensorFlow вы можете выполнить отсечение градиента здесь перед запуском оптимизатора.

В общем, я думаю, это звучит так, как будто вы наткнулись на реальную проблему исследования. Обычно эти большие градиенты имеют вескую причину в модели, к которой можно обратиться с осторожной продуманностью. Разница в какой-то оценке Монте-Карло? Плохо ли работает целевая функция?

Относительно того, почему не помогает использование естественных градиентов. Естественные градиенты используют матрицу Фишера в качестве предварительного условия для выполнения оптимизации второго порядка. Это может привести к довольно агрессивным движениям в пространстве параметров. В некоторых случаях (когда имеются пригодные отношения сопряженности), эти агрессивные действия могут значительно ускорить оптимизацию. Этот случай, с вероятностью Пуассона, не является тем, где существуют отношения сопряженности, которые обязательно помогут оптимизации. Фактически, предварительный кондиционер Фишера часто может быть вредным, особенно когда вариационные параметры не близки к оптимальным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...