Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keras-team
GitHub Repository: keras-team/keras-io
Path: blob/master/guides/sequential_model.py
3273 views
1
"""
2
Title: The Sequential model
3
Author: [fchollet](https://twitter.com/fchollet)
4
Date created: 2020/04/12
5
Last modified: 2023/06/25
6
Description: Complete guide to the Sequential model.
7
Accelerator: GPU
8
"""
9
10
"""
11
## Setup
12
13
"""
14
15
import keras
16
from keras import layers
17
from keras import ops
18
19
"""
20
## When to use a Sequential model
21
22
A `Sequential` model is appropriate for **a plain stack of layers**
23
where each layer has **exactly one input tensor and one output tensor**.
24
25
Schematically, the following `Sequential` model:
26
"""
27
28
# Define Sequential model with 3 layers
29
model = keras.Sequential(
30
[
31
layers.Dense(2, activation="relu", name="layer1"),
32
layers.Dense(3, activation="relu", name="layer2"),
33
layers.Dense(4, name="layer3"),
34
]
35
)
36
# Call model on a test input
37
x = ops.ones((3, 3))
38
y = model(x)
39
40
"""
41
is equivalent to this function:
42
"""
43
44
# Create 3 layers
45
layer1 = layers.Dense(2, activation="relu", name="layer1")
46
layer2 = layers.Dense(3, activation="relu", name="layer2")
47
layer3 = layers.Dense(4, name="layer3")
48
49
# Call layers on a test input
50
x = ops.ones((3, 3))
51
y = layer3(layer2(layer1(x)))
52
53
"""
54
A Sequential model is **not appropriate** when:
55
56
- Your model has multiple inputs or multiple outputs
57
- Any of your layers has multiple inputs or multiple outputs
58
- You need to do layer sharing
59
- You want non-linear topology (e.g. a residual connection, a multi-branch
60
model)
61
"""
62
63
"""
64
## Creating a Sequential model
65
66
You can create a Sequential model by passing a list of layers to the Sequential
67
constructor:
68
"""
69
70
model = keras.Sequential(
71
[
72
layers.Dense(2, activation="relu"),
73
layers.Dense(3, activation="relu"),
74
layers.Dense(4),
75
]
76
)
77
78
"""
79
Its layers are accessible via the `layers` attribute:
80
"""
81
82
model.layers
83
84
"""
85
You can also create a Sequential model incrementally via the `add()` method:
86
"""
87
88
model = keras.Sequential()
89
model.add(layers.Dense(2, activation="relu"))
90
model.add(layers.Dense(3, activation="relu"))
91
model.add(layers.Dense(4))
92
93
"""
94
Note that there's also a corresponding `pop()` method to remove layers:
95
a Sequential model behaves very much like a list of layers.
96
"""
97
98
model.pop()
99
print(len(model.layers)) # 2
100
101
"""
102
Also note that the Sequential constructor accepts a `name` argument, just like
103
any layer or model in Keras. This is useful to annotate TensorBoard graphs
104
with semantically meaningful names.
105
"""
106
107
model = keras.Sequential(name="my_sequential")
108
model.add(layers.Dense(2, activation="relu", name="layer1"))
109
model.add(layers.Dense(3, activation="relu", name="layer2"))
110
model.add(layers.Dense(4, name="layer3"))
111
112
"""
113
## Specifying the input shape in advance
114
115
Generally, all layers in Keras need to know the shape of their inputs
116
in order to be able to create their weights. So when you create a layer like
117
this, initially, it has no weights:
118
"""
119
120
layer = layers.Dense(3)
121
layer.weights # Empty
122
123
"""
124
It creates its weights the first time it is called on an input, since the shape
125
of the weights depends on the shape of the inputs:
126
"""
127
128
# Call layer on a test input
129
x = ops.ones((1, 4))
130
y = layer(x)
131
layer.weights # Now it has weights, of shape (4, 3) and (3,)
132
133
"""
134
Naturally, this also applies to Sequential models. When you instantiate a
135
Sequential model without an input shape, it isn't "built": it has no weights
136
(and calling
137
`model.weights` results in an error stating just this). The weights are created
138
when the model first sees some input data:
139
"""
140
141
model = keras.Sequential(
142
[
143
layers.Dense(2, activation="relu"),
144
layers.Dense(3, activation="relu"),
145
layers.Dense(4),
146
]
147
) # No weights at this stage!
148
149
# At this point, you can't do this:
150
# model.weights
151
152
# You also can't do this:
153
# model.summary()
154
155
# Call the model on a test input
156
x = ops.ones((1, 4))
157
y = model(x)
158
print("Number of weights after calling the model:", len(model.weights)) # 6
159
160
"""
161
Once a model is "built", you can call its `summary()` method to display its
162
contents:
163
"""
164
165
model.summary()
166
167
"""
168
However, it can be very useful when building a Sequential model incrementally
169
to be able to display the summary of the model so far, including the current
170
output shape. In this case, you should start your model by passing an `Input`
171
object to your model, so that it knows its input shape from the start:
172
"""
173
174
model = keras.Sequential()
175
model.add(keras.Input(shape=(4,)))
176
model.add(layers.Dense(2, activation="relu"))
177
178
model.summary()
179
180
"""
181
Note that the `Input` object is not displayed as part of `model.layers`, since
182
it isn't a layer:
183
"""
184
185
model.layers
186
187
"""
188
Models built with a predefined input shape like this always have weights (even
189
before seeing any data) and always have a defined output shape.
190
191
In general, it's a recommended best practice to always specify the input shape
192
of a Sequential model in advance if you know what it is.
193
"""
194
195
"""
196
## A common debugging workflow: `add()` + `summary()`
197
198
When building a new Sequential architecture, it's useful to incrementally stack
199
layers with `add()` and frequently print model summaries. For instance, this
200
enables you to monitor how a stack of `Conv2D` and `MaxPooling2D` layers is
201
downsampling image feature maps:
202
"""
203
204
model = keras.Sequential()
205
model.add(keras.Input(shape=(250, 250, 3))) # 250x250 RGB images
206
model.add(layers.Conv2D(32, 5, strides=2, activation="relu"))
207
model.add(layers.Conv2D(32, 3, activation="relu"))
208
model.add(layers.MaxPooling2D(3))
209
210
# Can you guess what the current output shape is at this point? Probably not.
211
# Let's just print it:
212
model.summary()
213
214
# The answer was: (40, 40, 32), so we can keep downsampling...
215
216
model.add(layers.Conv2D(32, 3, activation="relu"))
217
model.add(layers.Conv2D(32, 3, activation="relu"))
218
model.add(layers.MaxPooling2D(3))
219
model.add(layers.Conv2D(32, 3, activation="relu"))
220
model.add(layers.Conv2D(32, 3, activation="relu"))
221
model.add(layers.MaxPooling2D(2))
222
223
# And now?
224
model.summary()
225
226
# Now that we have 4x4 feature maps, time to apply global max pooling.
227
model.add(layers.GlobalMaxPooling2D())
228
229
# Finally, we add a classification layer.
230
model.add(layers.Dense(10))
231
232
"""
233
Very practical, right?
234
235
236
"""
237
238
"""
239
## What to do once you have a model
240
241
Once your model architecture is ready, you will want to:
242
243
- Train your model, evaluate it, and run inference. See our
244
[guide to training & evaluation with the built-in loops](
245
/guides/training_with_built_in_methods/)
246
- Save your model to disk and restore it. See our
247
[guide to serialization & saving](/guides/serialization_and_saving/).
248
"""
249
250
"""
251
## Feature extraction with a Sequential model
252
253
Once a Sequential model has been built, it behaves like a
254
[Functional API model](/guides/functional_api/).
255
This means that every layer has an `input`
256
and `output` attribute. These attributes can be used to do neat things, like
257
quickly creating a model that extracts the outputs of all intermediate layers in a
258
Sequential model:
259
"""
260
261
initial_model = keras.Sequential(
262
[
263
keras.Input(shape=(250, 250, 3)),
264
layers.Conv2D(32, 5, strides=2, activation="relu"),
265
layers.Conv2D(32, 3, activation="relu"),
266
layers.Conv2D(32, 3, activation="relu"),
267
]
268
)
269
feature_extractor = keras.Model(
270
inputs=initial_model.inputs,
271
outputs=[layer.output for layer in initial_model.layers],
272
)
273
274
# Call feature extractor on test input.
275
x = ops.ones((1, 250, 250, 3))
276
features = feature_extractor(x)
277
278
"""
279
Here's a similar example that only extract features from one layer:
280
"""
281
282
initial_model = keras.Sequential(
283
[
284
keras.Input(shape=(250, 250, 3)),
285
layers.Conv2D(32, 5, strides=2, activation="relu"),
286
layers.Conv2D(32, 3, activation="relu", name="my_intermediate_layer"),
287
layers.Conv2D(32, 3, activation="relu"),
288
]
289
)
290
feature_extractor = keras.Model(
291
inputs=initial_model.inputs,
292
outputs=initial_model.get_layer(name="my_intermediate_layer").output,
293
)
294
# Call feature extractor on test input.
295
x = ops.ones((1, 250, 250, 3))
296
features = feature_extractor(x)
297
298
"""
299
## Transfer learning with a Sequential model
300
301
Transfer learning consists of freezing the bottom layers in a model and only training
302
the top layers. If you aren't familiar with it, make sure to read our [guide
303
to transfer learning](/guides/transfer_learning/).
304
305
Here are two common transfer learning blueprint involving Sequential models.
306
307
First, let's say that you have a Sequential model, and you want to freeze all
308
layers except the last one. In this case, you would simply iterate over
309
`model.layers` and set `layer.trainable = False` on each layer, except the
310
last one. Like this:
311
312
```python
313
model = keras.Sequential([
314
keras.Input(shape=(784)),
315
layers.Dense(32, activation='relu'),
316
layers.Dense(32, activation='relu'),
317
layers.Dense(32, activation='relu'),
318
layers.Dense(10),
319
])
320
321
# Presumably you would want to first load pre-trained weights.
322
model.load_weights(...)
323
324
# Freeze all layers except the last one.
325
for layer in model.layers[:-1]:
326
layer.trainable = False
327
328
# Recompile and train (this will only update the weights of the last layer).
329
model.compile(...)
330
model.fit(...)
331
```
332
333
Another common blueprint is to use a Sequential model to stack a pre-trained
334
model and some freshly initialized classification layers. Like this:
335
336
```python
337
# Load a convolutional base with pre-trained weights
338
base_model = keras.applications.Xception(
339
weights='imagenet',
340
include_top=False,
341
pooling='avg')
342
343
# Freeze the base model
344
base_model.trainable = False
345
346
# Use a Sequential model to add a trainable classifier on top
347
model = keras.Sequential([
348
base_model,
349
layers.Dense(1000),
350
])
351
352
# Compile & train
353
model.compile(...)
354
model.fit(...)
355
```
356
357
If you do transfer learning, you will probably find yourself frequently using
358
these two patterns.
359
"""
360
361
"""
362
That's about all you need to know about Sequential models!
363
364
To find out more about building models in Keras, see:
365
366
- [Guide to the Functional API](/guides/functional_api/)
367
- [Guide to making new Layers & Models via subclassing](/guides/making_new_layers_and_models_via_subclassing/)
368
"""
369
370