Как получить значение потери в правиле обновления цепочки

Я пытаюсь изменить класс SGDRule(optimizer.UpdateRule) цепочки, чтобы сделать мой оригинальный оптимизатор.

Чтобы добиться того, что я хочу, мне нужно получить не только градиент, но и потери.

Перед созданием градиента обратным распространением должен быть пройден прямой путь, который приводит к потерям. Мне нужна эта потеря.

Проблема в том, что я должен получить доступ к потере из кода update_core_gpu(self, param) в классе.

Я узнал, что объект Classifier имеет потерю в качестве атрибута. Однако я не знаю, как получить доступ к объекту из правила обновления.

В качестве альтернативы я рассматривал возможность использования объекта Reporter, к которому я могу получить доступ из кода. Я знаю, как передать значение репортеру, но понятия не имею, как получить потери, которые есть у репортера.

Кто-нибудь знает, как получить текущую потерю в коде правила обновления?


person T.Y    schedule 02.10.2019    source источник


Ответы (1)


Если вы используете модель, которая содержит потери, например. Classifier, один простой, но, возможно, менее элегантный способ сделать это — просто передать модель Optimizer, а затем каждому UpdateRule при построении в Optimizer.create_update_rule. Если вы не хотите передавать модель, вы, вероятно, могли бы передать лямбду, которая возвращает потери из модели.

Другой, возможно, более чистый подход, если он достаточен для вашего случая, заключается в реализации хука оптимизатора, аналогичного тому, как отсечение градиента реализовано в Chainer. См. https://github.com/chainer/chainer/blob/master/chainer/optimizer_hooks/gradient_clipping.py#L56. Вы можете получить потери через opt.target.loss (opt.target — ваша модель) и, например, обновить градиент до шага оптимизации.

person hvy    schedule 07.10.2019
comment
Спасибо за помощь! Хук оптимизатора, кажется, то, что я должен попробовать, потому что я надеюсь, что мой оптимизатор сможет заменить существующие оптимизаторы без каких-либо изменений в других кодах. Поскольку я не знаком с хуком, я хочу спросить о нем для уточнения. Могу ли я получить доступ к потерям, которые я получаю в ловушке из кода правила обновления? Или надо все сделать для правила обновления в хуке? Спасибо. - person T.Y; 08.10.2019
comment
С технической точки зрения, поскольку у вас есть доступ к оптимизатору opt в хуке, вы можете получить параметры, используя opt.target.params, и для каждого параметра p вы можете получить правило обновления через p.update_rule. Затем вы можете изменить правило обновления по своему усмотрению, например. сохранение потери в некоторых атрибутах для последующего доступа к ней в обновлении. Это вопрос разделения ответственности. В идеале хук должен выполнять только любую предварительную/постобработку, связанную с обновлением, в вашем случае что-то, что зависит от потери, но не самого обновления (что может помешать другим хукам). - person hvy; 09.10.2019
comment
Еще раз спасибо! Я до сих пор не уверен в этом, но я так думал. В каталоге chainer/optimizer_hooks я должен написать класс ловушек (myhook). Когда я создаю объект своего класса оптимизатора, myopt(optimizer.GradientMethod), я могу получить доступ к объекту как «я», и я должен написать self.add_hook(chainer.optimizer_hooks.myhook()) в инициализаторе класса myopt. Затем у меня есть доступ как к цели, так и к update_rule из хука, как вы написали. Ваше предложение очень полезно. Спасибо. - person T.Y; 10.10.2019