[PYTHON] [TensorFlow] Resolve "ValueError: Die mit tf.function dekorierte Funktion hat versucht, Variablen beim nicht ersten Aufruf zu erstellen."

Funktion mit Optimierer oder Modell als Eingabe stirbt mit "versucht, Variablen beim nicht ersten Aufruf zu erstellen"

Ein Memorandum, weil ich in eine unerwartete Falle geraten bin, wenn ich dachte, dass ich nicht beabsichtige, eine andere Variable als den ersten Modellaufruf (Build) zu deklarieren.

Annahme

TensorFlow2 (Ich habe es um 2.5 Uhr pro Nacht bestätigt)

Das Erstellen von tf.Variable in tf.function ist verboten

  1. Die Funktion arbeitet nach dem Sichern grundsätzlich im selben Speicherbereich.
  2. tf.Variable ordnet einen neuen Speicherbereich zu und erstellt eine Variable.
  3. Daher verbraucht jedes Mal, wenn eine neue Variable erstellt wird, neuer Speicher, was zu einem Fehler führt.

@tf.function
def f(x):
  v = tf.Variable(1.0)
  v.assign_add(x)
  return v

with assert_raises(ValueError):
  f(1.0)

Caught expected exception 
  <class 'ValueError'>: in user code:

    <ipython-input-17-73e410646579>:3 f  *
        v = tf.Variable(1.0)
    /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/variables.py:262 __call__  **
        return cls._variable_v2_call(*args, **kwargs)
    /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/variables.py:256 _variable_v2_call
        shape=shape)
    /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/variables.py:67 getter
        return captured_getter(captured_previous, **kwargs)
    /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py:702 invalid_creator_scope
        "tf.function-decorated function tried to create "

Es kann nur eine Deklaration einer Python-Variablen sein. Da bei jedem Aufruf der Funktion derselbe Speicherbereich recycelt und verwendet wird.


@tf.function
def f(x):
    v = tf.ones((5, 5), dtype=tf.float32)
    return v
# raises no error!

Hauptthema

Die Funktion tf.keras.models.Model als Eingabe verursacht einen unerwarteten Fehler.

@tf.function
def call(model1: tf.keras.models.Model, inputs: tf.Tensor):
    return model1(inputs)


if __name__ == '__main__':
    model1 = tf.keras.Sequential([
        tf.keras.layers.Dense(16),
        tf.keras.layers.Dense(4)

    ])
    model2 = tf.keras.Sequential([
        tf.keras.layers.Dense(16),
        tf.keras.layers.Dense(4)
    ])
    inputs = tf.ones((10, 10), dtype=tf.float32)
    call(model1, inputs)  # raises no error!
    call(model2, inputs)  # raises an error! "tf.function-decorated function tried to create variables on non-first call"

Der Punkt ist, dass das Keras-Modell beim ersten Aufruf eine Variable wie eine Gewichtsmatrix erstellt. Wenn Sie dieser Aufruffunktion zwei nicht erstellte Modelle als Argumente übergeben, kommt es daher zu einem Unfall beim Versuch, das Gewicht des zweiten Modells beim zweiten Aufruf zu erhöhen! !!

Lösung


# @tf.Funktion ist nicht direkt angehängt
def call(model1: tf.keras.models.Model, inputs: tf.Tensor):
    return model1(inputs)


if __name__ == '__main__':
    model1 = tf.keras.Sequential([
        tf.keras.layers.Dense(16),
        tf.keras.layers.Dense(4)

    ])
    model2 = tf.keras.Sequential([
        tf.keras.layers.Dense(16),
        tf.keras.layers.Dense(4)
    ])
    inputs = tf.ones((10, 10), dtype=tf.float32)
    #Funktionen sind auch Objekte in Python. Generieren Sie eine Funktion für jedes Modell.
    model1_call = tf.function(call)
    model2_call = tf.function(call)
    model1_call(model1, inputs)
    model2_call(model2, inputs)

tf.function hört auf, direkt in die Funktionsdefinition zu schreiben, und erstellt für jedes Modell ein Funktionsobjekt. Metaprogrammierungskonzepte wie Dekoratoren und Funktionen höherer Ordnung sind für Python-Anfänger schwierig, daher ist es wichtig, dem Grund nicht genau zu folgen.

Wenn Sie wissen möchten, warum Sie dies tun können, sollten Sie sich an einen Python-Dekorateur, eine Funktion höherer Ordnung usw. wenden.

Zusammenfassung

Eager Execution ist zu langsam, um beim Schreiben komplizierter und vieler Schritte auf der GPU darüber zu sprechen. Daher möchte ich tf.function verwenden, um die Berechnungseffizienz zu erreichen, aber TF2 wurde gerade veröffentlicht. Es ist leicht, auf Fehler zu stoßen, die keinen Sinn ergeben, weil die Funktion zu schwach ist.

Wir werden weiterhin viel Wissen über tf2 und Deeplearning sammeln, also folgen Sie uns bitte mit LGTM!

Recommended Posts

[TensorFlow] Resolve "ValueError: Die mit tf.function dekorierte Funktion hat versucht, Variablen beim nicht ersten Aufruf zu erstellen."
Der Fehler der mit tf.function dekorierten Funktion hat versucht, Variablen beim nicht ersten Aufruf zu erstellen. In tensorflow.keras