Потеря, добавленная в пользовательский слой в tenorflow 2, очищается при компиляции - PullRequest
2 голосов
/ 12 апреля 2020

Я пытаюсь перенести реализацию удаления бетона в кератах в https://github.com/yaringal/ConcreteDropout/blob/master/concrete-dropout-keras.ipynb на тензор потока 2. Это в основном просто, поскольку в tf 2 встроена большая часть API-интерфейса keras. Тем не менее, пользовательские потери очищаются перед установкой.

После того, как модель определена и перед ее компиляцией, я вижу, что потери для каждого конкретного слоя выпадения были добавлены к потерям модели по линии self.layer.add_loss(regularizer) запускается при построении слоев:

>>> print(model.losses)
[<tf.Tensor: id=64, shape=(), dtype=float32, numpy=-8.4521576e-05>, <tf.Tensor: id=168, shape=(), dtype=float32, numpy=-0.000650166>, <tf.Tensor: id=272, shape=(), dtype=float32, numpy=-0.000650166>, <tf.Tensor: id=376, shape=(), dtype=float32, numpy=-0.000650166>, <tf.Tensor: id=479, shape=(), dtype=float32, numpy=-0.000650166>]

Однако после компиляции model.losses становится пустым списком, и утверждение assert len(model.losses) == 5 не выполняется. Если я решу проигнорировать утверждение, тот факт, что потери слоя игнорируются, проявляется в предупреждении WARNING:tensorflow:Gradients do not exist for variables ['concrete_dropout/p_logit:0', 'concrete_dropout_1/p_logit:0', 'concrete_dropout_2/p_logit:0', 'concrete_dropout_3/p_logit:0', 'concrete_dropout_4/p_logit:0'] when minimizing the loss. при обучении модели.

После поиска в коде компиляции в https://github.com/tensorflow/tensorflow/blob/r2.0/tensorflow/python/keras/engine/training.py#L184 Я считаю, что проблемные c строки

    # Clear any `_eager_losses` that was added.
    self._clear_losses()

Почему это делается при компиляции модели? И как я могу добавить потери на слой в tenorflow 2, если это не так?

1 Ответ

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

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

self.layer.add_loss(lambda: regularizer)
...