проблема tf.keras (tf2): не удается запустить пользовательские градиентные слои, ошибка OperatorNotAllowedInGraphError. Может быть вызвано API tf.Keras

#deep-learning #tensorflow2.0 #keras-layer #tf.keras #generative-adversarial-network

#глубокое обучение #tensorflow2.0 #keras-layer #tf.keras #генеративная-состязательная-сеть

Вопрос:

Я разместил свой код на github (с доступным набором данных).

Проблема в том, что я хочу реализовать неконтролируемую сеть состязательного обучения домена (DANN) (см. Документ) с использованием кода tf2.keras, хотя большинство ответов — версии tf1 или чистые keras, они напрямую не учитывали изменение между tf1 и tf2 и просто отключили быстрое выполнение.

Когда я пытаюсь добавить пользовательский слой gradient_reversal в начале моего domain_classifier следующим образом:

 @tf.custom_gradient
def reverse_gradient(X, hp_lambda):
    """Flips the sign of the incoming gradient during training."""
    try:
        reverse_gradient.num_calls  = 1
    except AttributeError:
        reverse_gradient.num_calls = 1

    grad_name = "GradientReversal%d" % reverse_gradient.num_calls

    @ops.RegisterGradient(grad_name)
    def _flip_gradients(grad):
        return [tf.negative(grad) * hp_lambda]

    # g = K.get_session().graph
    with tf.Graph().as_default() as g:
        with g.gradient_override_map({'Identity': grad_name}):
            y = tf.identity(X)
    return y

from tensorflow.python.keras.engine.base_layer import Layer # I use base_layer, and most errors are coming from here.
class GradientReversal(Layer):
    """Layer that flips the sign of gradient during training."""

    def __init__(self, hp_lambda, **kwargs):
        super(GradientReversal, self).__init__(**kwargs)
        self.supports_masking = True
        self.hp_lambda = hp_lambda

    # @staticmethod
    def get_output_shape_for(input_shape):
        return input_shape

    def build(self, input_shape):
        # self.trainable_weights = []
        return

    def call(self, x, mask=None):
        return reverse_gradient(x, self.hp_lambda)

    def compute_output_shape(self, input_shape):
        return input_shape

    def get_config(self):
        config = {}
        base_config = super(GradientReversal, self).get_config()
        return dict(list(base_config.items())   list(config.items()))
 

Возникло много ошибок:

 Traceback (most recent call last):
File "D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonkerasenginebase_layer.py", line 1117, in _functional_construction_call
outputs = call_fn(cast_inputs, *args, **kwargs)
File "D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonautographimplapi.py", line 258, in wrapper
raise e.ag_error_metadata.to_exception(e)
tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: in user code:

D:/Skill-worker-research/Python code and example data/SupplementarySoftware_DeepHL_python/DeepHL_python/danntest/main.py:117 call  *
    return reverse_gradient(x, self.hp_lambda)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonopscustom_gradient.py:264 __call__  **
    return self._d(self._f, a, k)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonopscustom_gradient.py:220 decorated
    return _graph_mode_decorator(wrapped, args, kwargs)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonopscustom_gradient.py:325 _graph_mode_decorator
    result, grad_fn = f(*args)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonframeworkops.py:503 __iter__
    self._disallow_iteration()
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonframeworkops.py:499 _disallow_iteration
    self._disallow_in_graph_mode("iterating over `tf.Tensor`")
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonframeworkops.py:479 _disallow_in_graph_mode
    " this function with @tf.function.".format(task))

OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonkerasenginebase_layer.py", line 1124, in _functional_construction_call
'n"""')
TypeError: You are attempting to use Python control flow in a layer that was not declared to be dynamic. Pass `dynamic=True` to the class constructor.
Encountered error:
"""
in user code:

D:/Skill-worker-research/Python code and example data/SupplementarySoftware_DeepHL_python/DeepHL_python/danntest/main.py:117 call  *
    return reverse_gradient(x, self.hp_lambda)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonopscustom_gradient.py:264 __call__  **
    return self._d(self._f, a, k)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonopscustom_gradient.py:220 decorated
    return _graph_mode_decorator(wrapped, args, kwargs)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonopscustom_gradient.py:325 _graph_mode_decorator
    result, grad_fn = f(*args)
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonframeworkops.py:503 __iter__
    self._disallow_iteration()
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonframeworkops.py:499 _disallow_iteration
    self._disallow_in_graph_mode("iterating over `tf.Tensor`")
D:UsersxiqxiAnaconda3envstf2libsite-packagestensorflowpythonframeworkops.py:479 _disallow_in_graph_mode
    " this function with @tf.function.".format(task))

OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed in Graph execution. Use 
Eager execution or decorate this function with @tf.function.

"""

Process finished with exit code -1
 

Я заметил, что @tf.custom_gradient — это код tf2, но tf2 больше не использует tf.Graph() для генерации статического графика при построении сетевой структуры, поэтому я все равно пробую этот код:

 @tf.custom_gradient
def GradientReversalOperator(x):
    def grad(dy):
        return -1 * dy
    return x, grad
 

Но возникла другая ошибка. Я думаю, это потому, что класс GradientReversal наследует tf.keras.base_layer, который содержит грамматику tf1. Я не могу решить такую проблему, даже если перепробовал так много способов.

Я загрузил свой код и задал этот вопрос. Надеюсь, есть кто-то, кто может помочь мне решить проблему и рассказать мне, как работает tf.keras.base_layer, а также почему он недоступен в моем коде.

Я буду очень признателен, если вы дадите мне какие-либо советы.

Еще раз спасибо за вашу помощь!

Ответ №1:

Теперь я исправил проблему.

Удалить:

из слоя импорта tensorflow.python.keras.engine.base_layer

Для

из tensorflow.python.keras.слои импортируют слой

Но возникает другая ошибка:

 InternalError: Recorded operation 'GradientReversalOperator' returned too few gradients. Expected 3 but received 2