第一个模型 #

概述 #

我们将构建一个简单的神经网络来识别手写数字(MNIST 数据集),这是深度学习领域的 “Hello World”。

text
┌─────────────────────────────────────────────────────────────┐
│                    项目目标                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  输入: 手写数字图像 (28×28 像素)                            │
│                                                             │
│  ┌───────────────┐                                         │
│  │   ┌───┐       │                                         │
│  │   │ 7 │       │  → 神经网络 → 预测: "7"                  │
│  │   └───┘       │                                         │
│  └───────────────┘                                         │
│                                                             │
│  输出: 数字类别 (0-9)                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

完整代码 #

python
import keras
import numpy as np
import matplotlib.pyplot as plt

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

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

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(10, activation='softmax')
])

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

history = model.fit(
    x_train, y_train,
    epochs=5,
    batch_size=32,
    validation_split=0.1,
    verbose=1
)

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

predictions = model.predict(x_test[:5])
predicted_classes = np.argmax(predictions, axis=1)
print(f'预测结果: {predicted_classes}')
print(f'真实标签: {y_test[:5]}')

逐步解析 #

步骤 1:导入库 #

python
import keras
import numpy as np
import matplotlib.pyplot as plt
text
┌─────────────────────────────────────────────────────────────┐
│                    库的作用                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  keras ──────── 深度学习框架                                │
│  numpy ──────── 数值计算                                    │
│  matplotlib ──── 可视化绘图                                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

步骤 2:加载数据 #

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

print(f"训练集: {x_train.shape}, {y_train.shape}")
print(f"测试集: {x_test.shape}, {y_test.shape}")
text
┌─────────────────────────────────────────────────────────────┐
│                    MNIST 数据集                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  训练集: 60,000 张 28×28 灰度图像                           │
│  测试集: 10,000 张 28×28 灰度图像                           │
│                                                             │
│  标签: 0-9 的数字                                           │
│                                                             │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐                  │
│  │  5  │ │  0  │ │  4  │ │  1  │ │  9  │                  │
│  └─────┘ └─────┘ └─────┘ └─────┘ └─────┘                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

步骤 3:数据预处理 #

python
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
text
┌─────────────────────────────────────────────────────────────┐
│                    数据归一化                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  原始数据: 0-255 (像素值)                                   │
│                                                             │
│  归一化后: 0.0-1.0                                          │
│                                                             │
│  为什么归一化?                                              │
│  ├── 加速收敛                                               │
│  ├── 防止数值溢出                                           │
│  └── 提高模型稳定性                                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

步骤 4:构建模型 #

python
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(10, activation='softmax')
])
text
┌─────────────────────────────────────────────────────────────┐
│                    模型结构                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  输入层: 28×28 = 784 个像素                                 │
│  ┌─────────────────────────────────────────┐               │
│  │ Flatten: 28×28 → 784 维向量             │               │
│  └─────────────────────────────────────────┘               │
│                          │                                  │
│                          ▼                                  │
│  隐藏层: 128 个神经元                                      │
│  ┌─────────────────────────────────────────┐               │
│  │ Dense(128) + ReLU                       │               │
│  │ 参数: 784×128 + 128 = 100,480           │               │
│  └─────────────────────────────────────────┘               │
│                          │                                  │
│                          ▼                                  │
│  Dropout: 随机丢弃 20%                                      │
│  ┌─────────────────────────────────────────┐               │
│  │ Dropout(0.2) - 防止过拟合               │               │
│  └─────────────────────────────────────────┘               │
│                          │                                  │
│                          ▼                                  │
│  输出层: 10 个类别                                          │
│  ┌─────────────────────────────────────────┐               │
│  │ Dense(10) + Softmax                     │               │
│  │ 参数: 128×10 + 10 = 1,290               │               │
│  └─────────────────────────────────────────┘               │
│                                                             │
│  总参数: 101,770                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

步骤 5:编译模型 #

python
model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)
text
┌─────────────────────────────────────────────────────────────┐
│                    编译配置                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  optimizer (优化器)                                         │
│  └── adam: 自适应学习率优化器,适合大多数任务               │
│                                                             │
│  loss (损失函数)                                            │
│  └── sparse_categorical_crossentropy: 多分类交叉熵          │
│      适用于整数标签 (0, 1, 2, ...)                          │
│                                                             │
│  metrics (评估指标)                                         │
│  └── accuracy: 准确率                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

步骤 6:训练模型 #

python
history = model.fit(
    x_train, y_train,
    epochs=5,
    batch_size=32,
    validation_split=0.1,
    verbose=1
)
text
┌─────────────────────────────────────────────────────────────┐
│                    训练参数                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  epochs: 训练轮数                                           │
│  └── 整个数据集遍历 5 次                                    │
│                                                             │
│  batch_size: 批次大小                                       │
│  └── 每次更新使用 32 个样本                                 │
│                                                             │
│  validation_split: 验证集比例                               │
│  └── 10% 的训练数据用于验证                                 │
│                                                             │
│  verbose: 输出详细程度                                      │
│  └── 1: 显示进度条                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

步骤 7:评估模型 #

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

步骤 8:预测 #

python
predictions = model.predict(x_test[:5])
predicted_classes = np.argmax(predictions, axis=1)
print(f'预测结果: {predicted_classes}')
print(f'真实标签: {y_test[:5]}')

可视化训练过程 #

python
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

axes[0].plot(history.history['loss'], label='训练损失')
axes[0].plot(history.history['val_loss'], label='验证损失')
axes[0].set_xlabel('Epoch')
axes[0].set_ylabel('Loss')
axes[0].set_title('损失曲线')
axes[0].legend()

axes[1].plot(history.history['accuracy'], label='训练准确率')
axes[1].plot(history.history['val_accuracy'], label='验证准确率')
axes[1].set_xlabel('Epoch')
axes[1].set_ylabel('Accuracy')
axes[1].set_title('准确率曲线')
axes[1].legend()

plt.tight_layout()
plt.show()

可视化预测结果 #

python
def plot_predictions(images, labels, predictions, n=10):
    plt.figure(figsize=(12, 4))
    for i in range(n):
        plt.subplot(2, 5, i + 1)
        plt.imshow(images[i], cmap='gray')
        pred = np.argmax(predictions[i])
        true = labels[i]
        color = 'green' if pred == true else 'red'
        plt.title(f'预测: {pred}, 真实: {true}', color=color)
        plt.axis('off')
    plt.tight_layout()
    plt.show()

predictions = model.predict(x_test[:10])
plot_predictions(x_test, y_test, predictions)

模型摘要 #

python
model.summary()
text
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Layer (type)                         ┃ Output Shape        ┃    Param #   ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ flatten (Flatten)                    │ (None, 784)         │            0 │
├──────────────────────────────────────┼─────────────────────┼──────────────┤
│ dense (Dense)                        │ (None, 128)         │      100,480 │
├──────────────────────────────────────┼─────────────────────┼──────────────┤
│ dropout (Dropout)                    │ (None, 128)         │            0 │
├──────────────────────────────────────┼─────────────────────┼──────────────┤
│ dense_1 (Dense)                      │ (None, 10)          │        1,290 │
└──────────────────────────────────────┴─────────────────────┴──────────────┘
Total params: 101,770 (397.54 KB)
Trainable params: 101,770 (397.54 KB)
Non-trainable params: 0 (0.00 B)

关键概念总结 #

text
┌─────────────────────────────────────────────────────────────┐
│                    深度学习工作流                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 数据准备                                                │
│     加载 → 预处理 → 划分                                    │
│                                                             │
│  2. 模型构建                                                │
│     定义结构 → 配置层                                       │
│                                                             │
│  3. 模型编译                                                │
│     优化器 → 损失函数 → 指标                                │
│                                                             │
│  4. 模型训练                                                │
│     fit() → 迭代优化                                        │
│                                                             │
│  5. 模型评估                                                │
│     evaluate() → 测试性能                                   │
│                                                             │
│  6. 模型预测                                                │
│     predict() → 应用模型                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

下一步 #

现在你已经完成了第一个神经网络模型,接下来学习 核心概念,深入理解 Keras 的核心组件!

最后更新:2026-04-04