![]() | ![]() | ![]() |
Installieren
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
Wann wird ein sequentielles Modell verwendet?
Ein Sequential
Modell eignet sich für einen einfachen Stapel von Schichten, wobei jede Schicht genau einen Eingangstensor und einen Ausgangstensor hat .
Schematisch das folgende Sequential
Modell:
# Define Sequential model with 3 layers
model = keras.Sequential(
[
layers.Dense(2, activation="relu", name="layer1"),
layers.Dense(3, activation="relu", name="layer2"),
layers.Dense(4, name="layer3"),
]
)
# Call model on a test input
x = tf.ones((3, 3))
y = model(x)
entspricht dieser Funktion:
# Create 3 layers
layer1 = layers.Dense(2, activation="relu", name="layer1")
layer2 = layers.Dense(3, activation="relu", name="layer2")
layer3 = layers.Dense(4, name="layer3")
# Call layers on a test input
x = tf.ones((3, 3))
y = layer3(layer2(layer1(x)))
Ein sequentielles Modell ist nicht geeignet, wenn:
- Ihr Modell verfügt über mehrere Eingänge oder mehrere Ausgänge
- Jede Ihrer Ebenen verfügt über mehrere Eingänge oder mehrere Ausgänge
- Sie müssen Layer-Sharing durchführen
- Sie möchten eine nichtlineare Topologie (z. B. eine Restverbindung, ein Mehrzweigmodell).
Erstellen eines sequentiellen Modells
Sie können ein sequentielles Modell erstellen, indem Sie eine Liste von Ebenen an den sequentiellen Konstruktor übergeben:
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4),
]
)
Auf seine Ebenen kann über das layers
zugegriffen werden:
model.layers
[<tensorflow.python.keras.layers.core.Dense at 0x7f7d1d5c7898>, <tensorflow.python.keras.layers.core.Dense at 0x7f7d2f6e0a20>, <tensorflow.python.keras.layers.core.Dense at 0x7f7d16beb9b0>]
Sie können ein sequentielles Modell auch schrittweise über die add()
-Methode erstellen:
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu"))
model.add(layers.Dense(3, activation="relu"))
model.add(layers.Dense(4))
Beachten Sie, dass es auch eine entsprechende pop()
-Methode zum Entfernen von Ebenen gibt: Ein sequentielles Modell verhält sich sehr ähnlich wie eine Liste von Ebenen.
model.pop()
print(len(model.layers)) # 2
2
Beachten Sie auch , dass die sequenzielle Konstruktor ein akzeptiert name
Argument, wie jede Schicht oder Modell in Keras. Dies ist nützlich, um TensorBoard-Diagramme mit semantisch aussagekräftigen Namen zu versehen.
model = keras.Sequential(name="my_sequential")
model.add(layers.Dense(2, activation="relu", name="layer1"))
model.add(layers.Dense(3, activation="relu", name="layer2"))
model.add(layers.Dense(4, name="layer3"))
Festlegen der Eingabeform im Voraus
Im Allgemeinen müssen alle Ebenen in Keras die Form ihrer Eingaben kennen, um ihre Gewichte erstellen zu können. Wenn Sie also eine Ebene wie diese erstellen, hat sie zunächst keine Gewichte:
layer = layers.Dense(3)
layer.weights # Empty
[]
Es erstellt seine Gewichte beim ersten Aufruf einer Eingabe, da die Form der Gewichte von der Form der Eingaben abhängt:
# Call layer on a test input
x = tf.ones((1, 4))
y = layer(x)
layer.weights # Now it has weights, of shape (4, 3) and (3,)
[<tf.Variable 'dense_6/kernel:0' shape=(4, 3) dtype=float32, numpy= array([[-0.06262648, 0.36915624, -0.27826005], [-0.6703571 , -0.03467071, 0.80370367], [-0.00725174, 0.19120002, 0.34244013], [-0.20762473, -0.31104177, -0.26624495]], dtype=float32)>, <tf.Variable 'dense_6/bias:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>]
Dies gilt natürlich auch für sequentielle Modelle. Wenn Sie ein sequentielles Modell ohne Eingabeform instanziieren, wird es nicht "erstellt": Es hat keine Gewichte (und das Aufrufen von model.weights
führt zu einem Fehler, der genau dies angibt). Die Gewichte werden erstellt, wenn das Modell zum ersten Mal Eingabedaten sieht:
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4),
]
) # No weights at this stage!
# At this point, you can't do this:
# model.weights
# You also can't do this:
# model.summary()
# Call the model on a test input
x = tf.ones((1, 4))
y = model(x)
print("Number of weights after calling the model:", len(model.weights)) # 6
Number of weights after calling the model: 6
Sobald ein Modell "erstellt" ist, können Sie seine summary()
-Methode aufrufen, um seinen Inhalt anzuzeigen:
model.summary()
Model: "sequential_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_7 (Dense) (1, 2) 10 _________________________________________________________________ dense_8 (Dense) (1, 3) 9 _________________________________________________________________ dense_9 (Dense) (1, 4) 16 ================================================================= Total params: 35 Trainable params: 35 Non-trainable params: 0 _________________________________________________________________
Es kann jedoch sehr nützlich sein, wenn Sie ein sequentielles Modell inkrementell erstellen, um die Zusammenfassung des bisherigen Modells einschließlich der aktuellen Ausgabeform anzeigen zu können. In diesem Fall sollten Sie Ihr Modell , indem einen Start Input
- Objekt zu Ihrem Modell, so dass es seine Eingangsform von Anfang an weiß:
model = keras.Sequential()
model.add(keras.Input(shape=(4,)))
model.add(layers.Dense(2, activation="relu"))
model.summary()
Model: "sequential_4" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_10 (Dense) (None, 2) 10 ================================================================= Total params: 10 Trainable params: 10 Non-trainable params: 0 _________________________________________________________________
Man beachte , dass das Input
- Objekt nicht als Teil angezeigt wird model.layers
, da es nicht eine Schicht ist:
model.layers
[<tensorflow.python.keras.layers.core.Dense at 0x7f7d16b870f0>]
Eine einfache Alternative besteht darin, einfach ein input_shape
Argument an Ihre erste Ebene zu übergeben:
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu", input_shape=(4,)))
model.summary()
Model: "sequential_5" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_11 (Dense) (None, 2) 10 ================================================================= Total params: 10 Trainable params: 10 Non-trainable params: 0 _________________________________________________________________
Modelle, die mit einer vordefinierten Eingabeform wie dieser erstellt wurden, haben immer Gewichte (noch bevor Daten angezeigt werden) und haben immer eine definierte Ausgabeform.
Im Allgemeinen wird empfohlen, die Eingabeform eines sequentiellen Modells immer im Voraus anzugeben, wenn Sie wissen, um was es sich handelt.
Ein gängiger Debugging-Workflow: add()
+ summary()
Beim Erstellen einer neuen sequentiellen Architektur ist es hilfreich, Ebenen schrittweise mit add()
zu stapeln und häufig Modellzusammenfassungen zu drucken. Auf diese Weise können Sie beispielsweise überwachen, wie ein Stapel von Conv2D
und MaxPooling2D
Ebenen Bild-Feature-Maps MaxPooling2D
:
model = keras.Sequential()
model.add(keras.Input(shape=(250, 250, 3))) # 250x250 RGB images
model.add(layers.Conv2D(32, 5, strides=2, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
# Can you guess what the current output shape is at this point? Probably not.
# Let's just print it:
model.summary()
# The answer was: (40, 40, 32), so we can keep downsampling...
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(2))
# And now?
model.summary()
# Now that we have 4x4 feature maps, time to apply global max pooling.
model.add(layers.GlobalMaxPooling2D())
# Finally, we add a classification layer.
model.add(layers.Dense(10))
Model: "sequential_6" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 123, 123, 32) 2432 _________________________________________________________________ conv2d_1 (Conv2D) (None, 121, 121, 32) 9248 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 40, 40, 32) 0 ================================================================= Total params: 11,680 Trainable params: 11,680 Non-trainable params: 0 _________________________________________________________________ Model: "sequential_6" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 123, 123, 32) 2432 _________________________________________________________________ conv2d_1 (Conv2D) (None, 121, 121, 32) 9248 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 40, 40, 32) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 38, 38, 32) 9248 _________________________________________________________________ conv2d_3 (Conv2D) (None, 36, 36, 32) 9248 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 12, 12, 32) 0 _________________________________________________________________ conv2d_4 (Conv2D) (None, 10, 10, 32) 9248 _________________________________________________________________ conv2d_5 (Conv2D) (None, 8, 8, 32) 9248 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 4, 4, 32) 0 ================================================================= Total params: 48,672 Trainable params: 48,672 Non-trainable params: 0 _________________________________________________________________
Sehr praktisch, oder?
Was tun, wenn Sie ein Modell haben?
Sobald Ihre Modellarchitektur fertig ist, möchten Sie:
- Trainieren Sie Ihr Modell, bewerten Sie es und führen Sie Inferenzen durch. Lesen Sie unseren Leitfaden zur Schulung und Bewertung mit den integrierten Schleifen
- Speichern Sie Ihr Modell auf der Festplatte und stellen Sie es wieder her. Weitere Informationen finden Sie in unserer Anleitung zum Serialisieren und Speichern .
- Beschleunigen Sie das Modelltraining, indem Sie mehrere GPUs einsetzen. Lesen Sie unseren Leitfaden für Multi-GPU- und verteilte Schulungen .
Merkmalsextraktion mit einem sequentiellen Modell
Sobald ein sequentielles Modell erstellt wurde, verhält es sich wie ein funktionales API-Modell . Dies bedeutet, dass jede Ebene ein input
und output
hat. Diese Attribute können verwendet werden, um nette Dinge zu erledigen, z. B. schnell ein Modell zu erstellen, das die Ausgaben aller Zwischenebenen in einem sequentiellen Modell extrahiert:
initial_model = keras.Sequential(
[
keras.Input(shape=(250, 250, 3)),
layers.Conv2D(32, 5, strides=2, activation="relu"),
layers.Conv2D(32, 3, activation="relu"),
layers.Conv2D(32, 3, activation="relu"),
]
)
feature_extractor = keras.Model(
inputs=initial_model.inputs,
outputs=[layer.output for layer in initial_model.layers],
)
# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)
Hier ist ein ähnliches Beispiel, das nur Features aus einer Ebene extrahiert:
initial_model = keras.Sequential(
[
keras.Input(shape=(250, 250, 3)),
layers.Conv2D(32, 5, strides=2, activation="relu"),
layers.Conv2D(32, 3, activation="relu", name="my_intermediate_layer"),
layers.Conv2D(32, 3, activation="relu"),
]
)
feature_extractor = keras.Model(
inputs=initial_model.inputs,
outputs=initial_model.get_layer(name="my_intermediate_layer").output,
)
# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)
Übertragen Sie das Lernen mit einem sequentiellen Modell
Transferlernen besteht darin, die unteren Schichten in einem Modell einzufrieren und nur die oberen Schichten zu trainieren. Wenn Sie damit nicht vertraut sind, lesen Sie unbedingt unseren Leitfaden zum Lerntransfer .
Hier sind zwei gängige Blaupausen für das Transferlernen mit sequentiellen Modellen.
Angenommen, Sie haben ein sequentielles Modell und möchten alle Ebenen außer der letzten einfrieren. In diesem Fall würden Sie einfach über model.layers
iterieren und layer.trainable = False
auf jeder Ebene mit Ausnahme der letzten layer.trainable = False
. So was:
model = keras.Sequential([
keras.Input(shape=(784))
layers.Dense(32, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(10),
])
# Presumably you would want to first load pre-trained weights.
model.load_weights(...)
# Freeze all layers except the last one.
for layer in model.layers[:-1]:
layer.trainable = False
# Recompile and train (this will only update the weights of the last layer).
model.compile(...)
model.fit(...)
Ein weiterer gängiger Entwurf besteht darin, ein sequentielles Modell zu verwenden, um ein vorab trainiertes Modell und einige frisch initialisierte Klassifizierungsebenen zu stapeln. So was:
# Load a convolutional base with pre-trained weights
base_model = keras.applications.Xception(
weights='imagenet',
include_top=False,
pooling='avg')
# Freeze the base model
base_model.trainable = False
# Use a Sequential model to add a trainable classifier on top
model = keras.Sequential([
base_model,
layers.Dense(1000),
])
# Compile & train
model.compile(...)
model.fit(...)
Wenn Sie das Lernen übertragen, werden Sie wahrscheinlich häufig diese beiden Muster verwenden.
Das ist ungefähr alles, was Sie über sequentielle Modelle wissen müssen!
Weitere Informationen zum Erstellen von Modellen in Keras finden Sie unter: