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.
TensorFlow2 (Ich habe es um 2.5 Uhr pro Nacht bestätigt)
@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!
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! !!
# @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.
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!