第一个模型 #
概述 #
我们将构建一个简单的神经网络来识别手写数字(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