Sequential 序列模型 #

什么是 Sequential 模型? #

Sequential 模型是 Keras 中最简单的模型类型,它将多个网络层线性堆叠在一起。

text
┌─────────────────────────────────────────────────────────────┐
│                    Sequential 模型结构                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  输入 ──► [层1] ──► [层2] ──► [层3] ──► 输出               │
│                                                             │
│  特点:                                                      │
│  ✅ 简单直观,易于理解                                      │
│  ✅ 适合初学者入门                                          │
│  ✅ 适合简单的前馈网络                                      │
│                                                             │
│  局限:                                                      │
│  ❌ 不支持多输入/多输出                                     │
│  ❌ 不支持层共享                                            │
│  ❌ 不支持复杂拓扑结构                                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

创建 Sequential 模型 #

方式一:列表方式 #

python
import keras

model = keras.Sequential([
    keras.layers.Dense(64, activation='relu', input_shape=(784,)),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

方式二:逐层添加 #

python
import keras

model = keras.Sequential()

model.add(keras.layers.Dense(64, activation='relu', input_shape=(784,)))
model.add(keras.layers.Dropout(0.2))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))

方式三:指定输入层 #

python
import keras

model = keras.Sequential([
    keras.layers.Input(shape=(784,)),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

指定输入形状 #

text
┌─────────────────────────────────────────────────────────────┐
│                    输入形状指定                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  方式 1: 在第一个层指定 input_shape                          │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Dense(64, input_shape=(784,))                       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  方式 2: 使用 Input 层                                      │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ Input(shape=(784,))                                 │   │
│  │ Dense(64)                                           │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  方式 3: 使用 build 方法                                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ model.build(input_shape=(None, 784))                │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  注意: batch 维度不需要指定                                 │
│  input_shape=(784,) 表示 (batch_size, 784)                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

不同数据类型的输入形状 #

python
import keras

image_model = keras.Sequential([
    keras.layers.Conv2D(32, 3, input_shape=(28, 28, 3)),
    keras.layers.MaxPooling2D(),
    keras.layers.Flatten(),
    keras.layers.Dense(10)
])

sequence_model = keras.Sequential([
    keras.layers.Embedding(10000, 128, input_length=100),
    keras.layers.LSTM(64),
    keras.layers.Dense(10)
])

video_model = keras.Sequential([
    keras.layers.Conv3D(32, 3, input_shape=(16, 112, 112, 3)),
    keras.layers.GlobalAveragePooling3D(),
    keras.layers.Dense(10)
])

模型摘要 #

python
model.summary()
text
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Layer (type)                         ┃ Output Shape        ┃    Param #   ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ dense (Dense)                        │ (None, 64)          │       50,240 │
├──────────────────────────────────────┼─────────────────────┼──────────────┤
│ dropout (Dropout)                    │ (None, 64)          │            0 │
├──────────────────────────────────────┼─────────────────────┼──────────────┤
│ dense_1 (Dense)                      │ (None, 32)          │        2,080 │
├──────────────────────────────────────┼─────────────────────┼──────────────┤
│ dense_2 (Dense)                      │ (None, 10)          │          330 │
└──────────────────────────────────────┴─────────────────────┴──────────────┘
Total params: 52,650 (205.66 KB)
Trainable params: 52,650 (205.66 KB)
Non-trainable params: 0 (0.00 B)

编译模型 #

python
model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.001),
    loss=keras.losses.CategoricalCrossentropy(),
    metrics=[
        'accuracy',
        keras.metrics.Precision(),
        keras.metrics.Recall()
    ]
)

训练模型 #

基础训练 #

python
history = model.fit(
    x_train, y_train,
    epochs=10,
    batch_size=32
)

完整训练配置 #

python
history = model.fit(
    x_train, y_train,
    epochs=50,
    batch_size=32,
    validation_data=(x_val, y_val),
    validation_split=0.1,
    shuffle=True,
    verbose=1,
    callbacks=[
        keras.callbacks.EarlyStopping(patience=5),
        keras.callbacks.ModelCheckpoint('best_model.keras')
    ]
)
text
┌─────────────────────────────────────────────────────────────┐
│                    训练参数说明                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  x_train, y_train: 训练数据和标签                           │
│                                                             │
│  epochs: 训练轮数,完整遍历数据集的次数                      │
│                                                             │
│  batch_size: 每次梯度更新使用的样本数                       │
│  ├── 较小 (16-32): 更新频繁,训练慢,泛化好                 │
│  └── 较大 (64-256): 更新少,训练快,可能陷入局部最优        │
│                                                             │
│  validation_data: 验证数据                                  │
│                                                             │
│  validation_split: 从训练数据中划分验证集比例               │
│                                                             │
│  shuffle: 每个 epoch 前是否打乱数据                         │
│                                                             │
│  verbose: 输出详细程度 (0=静默, 1=进度条, 2=每轮一行)       │
│                                                             │
│  callbacks: 回调函数列表                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

评估与预测 #

评估模型 #

python
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=0)
print(f'测试损失: {test_loss:.4f}')
print(f'测试准确率: {test_acc:.4f}')

预测 #

python
predictions = model.predict(x_test)

predicted_classes = predictions.argmax(axis=1)

probabilities = model.predict(x_test[:1])
print(f'预测概率: {probabilities}')

完整示例:MNIST 分类 #

python
import keras
import numpy as np

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

x_train = x_train.reshape(-1, 784).astype('float32') / 255.0
x_test = x_test.reshape(-1, 784).astype('float32') / 255.0

model = keras.Sequential([
    keras.layers.Input(shape=(784,)),
    keras.layers.Dense(512, activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(256, activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(10, activation='softmax')
])

model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.001),
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

history = model.fit(
    x_train, y_train,
    epochs=20,
    batch_size=128,
    validation_split=0.1,
    callbacks=[
        keras.callbacks.EarlyStopping(
            monitor='val_loss',
            patience=3,
            restore_best_weights=True
        )
    ]
)

test_loss, test_acc = model.evaluate(x_test, y_test, verbose=0)
print(f'\n测试集准确率: {test_acc:.4f}')

完整示例:图像分类 CNN #

python
import keras

(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()

x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0

model = keras.Sequential([
    keras.layers.Input(shape=(32, 32, 3)),
    
    keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(32, 3, padding='same', activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.MaxPooling2D(),
    keras.layers.Dropout(0.25),
    
    keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.Conv2D(64, 3, padding='same', activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.MaxPooling2D(),
    keras.layers.Dropout(0.25),
    
    keras.layers.Flatten(),
    keras.layers.Dense(512, activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(10, activation='softmax')
])

model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

history = model.fit(
    x_train, y_train,
    epochs=50,
    batch_size=64,
    validation_split=0.1,
    callbacks=[
        keras.callbacks.EarlyStopping(patience=10, restore_best_weights=True)
    ]
)

模型操作 #

获取层信息 #

python
for layer in model.layers:
    print(f'{layer.name}: {layer.output_shape}')

first_layer = model.layers[0]
print(f'权重形状: {first_layer.kernel.shape}')

提取中间层输出 #

python
intermediate_model = keras.Model(
    inputs=model.inputs,
    outputs=model.layers[2].output
)
intermediate_output = intermediate_model.predict(x_test)

冻结层 #

python
for layer in model.layers[:-3]:
    layer.trainable = False

model.compile(optimizer='adam', loss='categorical_crossentropy')

下一步 #

现在你已经掌握了 Sequential 模型,接下来学习 Functional API,构建更复杂的网络结构!

最后更新:2026-04-04