Как мы можем применить ограничение к значению настраиваемой обучаемой переменной? - PullRequest
1 голос
/ 21 апреля 2020

Я определил пользовательскую переменную для определенного слоя. Я бы хотел, чтобы эта переменная принимала только положительные значения. Keras предоставляет ограничения, но мне кажется, что они предназначены только для параметров kernel_constraint и bias_constraint слоев Keras.

Существует ли (простой) способ ограничения значения пользовательского Обучаемая переменная (т.е. созданная методом add_weight) в Керасе (и TensorFlow)?

Ответы [ 3 ]

1 голос
/ 21 апреля 2020

Переменные Tensorflow поддерживают ограничения, включая переменные, созданные с помощью add_weight. См. Документы здесь .

Например, если вы хотите, чтобы переменная имела значения 0

self.add_weight(shape=some_shape, constraint=lambda x: tf.clip_by_value(x, 0, 1))

В общем, constraint должна быть функцией; эта функция принимает переменную в качестве входных данных и возвращает новое значение для переменной. В этом случае обрезается в 0 и 1.

Обратите внимание, что способ, которым это реализовано, заключается в том, что эта функция просто вызывается для переменной после того, как оптимизатор выполняет свой шаг градиента. Это означает, что значения, которые «хотят» быть вне диапазона, будут обрезаны до жестких 0 и 1, и вы можете получить множество значений именно на этой границе. Так что, как отмечает @ y.selivonchyk, это не «математически правильно», то есть градиенты не знают об ограничении. Возможно, вы захотите объединить ограничение с регуляризацией, которую они предлагают, для лучшего эффекта.

1 голос
/ 22 апреля 2020

Я просто хочу добавить к ответу, данному @ xdurch0, что вы, если хотите, чтобы они были неотрицательными, уже есть встроенное ограничение NonNeg, которое точно делает это, и вы можно использовать его следующим образом:

self.add_weight(..., constraint=tf.keras.constraints.NonNeg())
1 голос
/ 21 апреля 2020

Маловероятно, чтобы существовал строгий математически обоснованный способ сохранения градиентов для этой переменной, чтобы она никогда не составляла sh ниже нуля. Тем не менее, вы можете добавить до вашей модели, что будет: «Переменная X должна оставаться неотрицательной» и увеличивать потери всякий раз, когда этот предварительный не выполняется. Это можно сделать следующим образом:

  1. Вычислить математическое выражение, которое будет положительным, только если ваша переменная отрицательна, что будет что-то вроде K.sum(K.relu(-var))
  2. Представьте результат этого выражения как второй выход модели
  3. . Примените к этому выходу линейную потерю, которая будет суммироваться с вашей тренировочной потерей (вы можете указать вес для этой суммы )

Это решение будет иметь недостатки: некоторые компоненты могут все еще быть отрицательными после итерации, поскольку «регуляризация» градиента будет отставать на одну итерацию (может быть исправлена ​​более строгим правилом). K.sum(K.relu(-var+1)); в зависимости от вашего веса потери вы можете обнулить компоненты этой переменной.

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