Keras

技术栈
AI 框架
deep-learningtensorflowneural-networkhigh-level-api

概览

Keras

Keras 是由 François Chollet 于 2015 年发布的高级神经网络 API,现为 TensorFlow 官方前端。它以模块化、用户友好著称,让开发者用极简代码快速构建和训练深度学习模型。

核心价值:

  • 极简 API:3 行代码定义神经网络,Sequential 模型开箱即用
  • 多后端支持:TensorFlow / JAX / PyTorch(Keras 3.0)
  • 全流程覆盖:层(Layers)、优化器、损失函数、回调、预处理层一应俱全
  • 调试友好model.summary()、TensorBoard 集成、即时执行

适用场景: 快速原型验证、教学演示、中小规模深度学习任务、迁移学习。

安装

环境准备

  • Python:>= 3.9(推荐 3.10 / 3.11)
  • pip:推荐 pip 23+
  • 可选 GPU:NVIDIA CUDA 11.8+ / cuDNN 8.6+
  • 虚拟环境:推荐 venv 或 conda 隔离

安装命令

方式一:pip 直接安装(推荐)

pip install tensorflow      # Keras 已内置在 TF 中
python -c "from tensorflow import keras; print(keras.__version__)"

方式二:Keras 3.0 多后端安装

# 仅安装 Keras(需自行安装后端:TF / JAX / PyTorch)
pip install keras

# 安装 + PyTorch 后端
pip install keras torch torchvision

# 安装 + JAX 后端
pip install keras jax jaxlib

设置后端(Keras 3.0)

export KERAS_BACKEND="tensorflow"   # 或 "jax" / "torch"

GPU 验证

import tensorflow as tf
print("GPU 可用:", tf.config.list_physical_devices('GPU'))

常见安装问题

Q1: ImportError: cannot import name 'keras' from 'tensorflow'

TensorFlow 版本过低(< 2.0)。升级:pip install --upgrade tensorflow

Q2: GPU 不可用

检查 CUDA 版本匹配 TF 要求。TF 2.15 需 CUDA 12.2。查看兼容矩阵:https://www.tensorflow.org/install/source#gpu

Q3: Keras 2 vs Keras 3 API 差异

Keras 3 默认不再绑定 TF,导入时若报 module 'keras' has no attribute 'xxx',检查是否同时安装了 kerastf.keras,两者不兼容,卸载其一。

示例

Keras MNIST 手写数字识别

目标

用 Keras Sequential API 构建一个简单 CNN,在 MNIST 数据集上达到 99%+ 准确率。

完整代码

import numpy as np
from tensorflow import keras
from tensorflow.keras import layers

# 1. 加载数据
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# 2. 预处理:归一化 + reshape(增加 channel 维度)
x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0
x_train = np.expand_dims(x_train, -1)   # (60000, 28, 28, 1)
x_test = np.expand_dims(x_test, -1)

# 3. One-hot 编码标签
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

# 4. 构建模型
model = keras.Sequential([
    layers.Conv2D(32, (3, 3), activation="relu", input_shape=(28, 28, 1)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation="relu"),
    layers.MaxPooling2D((2, 2)),
    layers.Flatten(),
    layers.Dropout(0.5),
    layers.Dense(128, activation="relu"),
    layers.Dense(10, activation="softmax"),
])

model.compile(
    optimizer="adam",
    loss="categorical_crossentropy",
    metrics=["accuracy"],
)

# 5. 训练
model.fit(x_train, y_train, batch_size=128, epochs=5, validation_split=0.1)

# 6. 评估
score = model.evaluate(x_test, y_test, verbose=0)
print(f"测试准确率: {score[1]:.4f}")

运行步骤

pip install tensorflow numpy
python mnist_cnn.py

预期输出

Epoch 1/5
422/422 ━━━━━━━━ 15s  ... accuracy: 0.9720
Epoch 5/5
422/422 ━━━━━━━━ 14s  ... accuracy: 0.9938
测试准确率: 0.9912

教程

Keras 入门教程:从 Sequential 到迁移学习

1. Keras 是什么?

Keras 是 TensorFlow 的官方高级 API,核心理念是"让深度学习变得简单"。它抽象了张量运算、自动微分、GPU 调度等底层细节,让开发者专注于模型架构。

三大编程范式

范式 API 适用场景
Sequential keras.Sequential 层堆叠的简单模型
Functional keras.Model 多输入/输出、共享层、残差连接
Subclassing class MyModel(keras.Model) 自定义训练逻辑、研究实验

2. Sequential 入门

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

Sequential 假设"输入→层1→层2→...→输出"的线性拓扑。input_shape 仅需在第一层指定。

3. Functional API:多输入多输出

inputs = keras.Input(shape=(784,))
x = layers.Dense(64, activation='relu')(inputs)
x = layers.Dense(64, activation='relu')(x)
outputs = layers.Dense(10, activation='softmax')(x)
model = keras.Model(inputs=inputs, outputs=outputs)

Functional API 的核心:层是函数,接受张量返回张量。这让你可以构建 DAG(有向无环图)——跳过连接、分支、合并等复杂拓扑。

4. Subclassing:完全控制

class MyModel(keras.Model):
    def __init__(self):
        super().__init__()
        self.dense1 = layers.Dense(64, activation='relu')
        self.dense2 = layers.Dense(10, activation='softmax')

    def call(self, inputs):
        x = self.dense1(inputs)
        return self.dense2(x)

Subclassing 适合研究场景,但不会自动暴露层结构——model.summary() 需先 build。

5. 回调(Callbacks)与训练监控

callbacks = [
    keras.callbacks.EarlyStopping(patience=3, restore_best_weights=True),
    keras.callbacks.ModelCheckpoint('best.keras', save_best_only=True),
    keras.callbacks.ReduceLROnPlateau(factor=0.5, patience=2),
]

model.fit(x_train, y_train, epochs=50, callbacks=callbacks, validation_split=0.1)

推荐底线配置:EarlyStopping + ModelCheckpoint 至少这两个。

6. 迁移学习实战(Keras 3.0)

# 加载预训练模型
base_model = keras.applications.EfficientNetV2B0(
    include_top=False,
    weights='imagenet',
    input_shape=(224, 224, 3)
)
base_model.trainable = False  # 冻结

# 添加自定义分类头
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.2)(x)
outputs = layers.Dense(10, activation='softmax')(x)
model = keras.Model(inputs, outputs)

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

先用冻结 backbone 训练分类头(5-10 epoch),再解冻微调(学习率降低 10x)。

7. 常见坑与调试

问题 原因 解决
shape mismatch Dense 输出与标签维度不一致 确认最后一层 units == num_classes
loss 不下降 学习率太大/太小 从 1e-3 开始,使用 ReduceLROnPlateau
OOM batch_size 太大 减小到 32 或 16
训练过拟合 数据少/无正则化 加 Dropout + 数据增强

思考题

  1. Functional API 相比 Sequential 的不可替代场景有哪些?
  2. BatchNormalizationactivation 之前还是之后?为什么?
  3. 迁移学习中为什么先冻结 backbone → 再微调,而不是直接全部训练?

参考资料

暂无参考文献