Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Das sequentielle Modell

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Konfiguration

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 0x7f65406f4cf8>,
 <tensorflow.python.keras.layers.core.Dense at 0x7f65407f4128>,
 <tensorflow.python.keras.layers.core.Dense at 0x7f652e69a9b0>]

Sie können ein sequentielles Modell auch schrittweise über die Methode add() 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.624763  ,  0.4083134 , -0.5529761 ],
        [ 0.6743641 , -0.5915712 , -0.7844806 ],
        [ 0.5746553 , -0.5919968 , -0.56293225],
        [ 0.0971899 , -0.7555427 , -0.44926038]], 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 ein 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
_________________________________________________________________

Beachten Sie, dass das Input nicht als Teil angezeigt wird model.layers , da es nicht eine Schicht ist:

model.layers
[<tensorflow.python.keras.layers.core.Dense at 0x7f65406b2dd8>]

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 solchen vordefinierten Eingabeform erstellt wurden, haben immer Gewichte (noch bevor Daten angezeigt werden) und 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:

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 iterieren Sie einfach über model.layers und setzen layer.trainable = False auf jeder Ebene mit Ausnahme der letzten. 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: