Skip to content

Keras - Model Compilation

使用 Sequential 或 Functional API 定义模型架构后,下一步是编译它。编译通过指定 optimizer(优化器)、loss function(损失函数)和 evaluation metrics(评估指标)来配置模型用于训练。编译完成后,模型就可以使用 fit 方法进行训练了。

compile 方法配置了学习过程。它需要几个关键参数:

model.compile(
optimizer='rmsprop', # 优化算法
loss=None, # 需要最小化的损失函数
metrics=None, # 需要监控的指标列表
loss_weights=None, # 可选的权重,用于不同输出(多输出模型)
weighted_metrics=None, # 根据 sample_weight 或 class_weight 计算加权指标
run_eagerly=False, # 如果为 True,模型将逐步运行(更易于调试,但速度较慢)
steps_per_execution=1, # 在单个 tf.function 调用中运行的批次数量
**kwargs
)

关键参数:

  • optimizer: 这决定了模型如何根据损失函数计算出的梯度来更新权重。它控制着学习过程。
    • 常见选择: 'adam', 'sgd', 'rmsprop',或者 tf.keras.optimizers.Adam(learning_rate=0.001) 这样的实例。
    • 为何重要: 优化器显著影响训练速度和收敛。Adam 通常是一个好的起点。
  • loss: 在训练过程中,衡量模型预测值与真实目标值之间差异的函数。优化器的目标是最小化这个损失。
    • 常见选择: 'binary_crossentropy'、'categorical_crossentropy'、'sparse_categorical_crossentropy'(用于分类);'mean_squared_error'、'mean_absolute_error'(用于回归);或者 tf.keras.losses.BinaryCrossentropy() 这样的实例。
    • 为何重要: 损失函数必须与问题的性质和输出层的激活函数相匹配(例如,分类问题使用带有 softmax/sigmoid 的交叉熵)。
  • metrics: 用于在训练和测试期间评估模型性能的指标列表。这些用于监控和报告,不直接影响权重更新。
    • 常见选择: ['accuracy'](用于分类)、['mae', 'mse'](用于回归),或者 [tf.keras.metrics.AUC(), tf.keras.metrics.Precision()] 这样的实例。
    • 为何重要: 指标提供了模型表现如何的人类可理解的洞察。

编译示例:

# 用于多类别分类模型
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss=tf.keras.losses.SparseCategoricalCrossentropy(), # 如果标签是整数,则使用此项
# loss='sparse_categorical_crossentropy', # 等价的字符串标识符
metrics=['accuracy'])
# 用于二元分类模型
# model.compile(optimizer='adam',
# loss='binary_crossentropy',
# metrics=['accuracy', tf.keras.metrics.AUC()])
# 用于回归模型
# model.compile(optimizer=tf.keras.optimizers.RMSprop(),
# loss='mean_squared_error',
# metrics=['mae'])

fit 方法会训练模型固定数量的 epoch(完整地遍历整个数据集的次数)。它接收训练数据、验证数据(可选)和训练配置参数。

history = model.fit(
x=None, # 输入训练数据(NumPy 数组、tf.data.Dataset 等)
y=None, # 目标训练数据(标签)
batch_size=None, # 每次梯度更新的样本数量
epochs=1, # 遍历整个数据集的次数
verbose='auto', # 详细模式 (0, 1, 或 2)
callbacks=None, # tf.keras.callbacks.Callback 实例列表
validation_split=0.0, # 用作验证数据的训练数据比例
validation_data=None, # 用于在每个 epoch 结束时评估损失和指标的数据(例如,(x_val, y_val) 或 Dataset)
shuffle=True, # 是否在每个 epoch 前打乱训练数据
class_weight=None, # 可选字典,将类别索引映射到权重值
sample_weight=None, # 可选的 NumPy 数组,包含训练样本的权重
initial_epoch=0, # 开始训练的 epoch(对于恢复训练很有用)
steps_per_epoch=None, # 每个 epoch 运行的总步数(批次)(与 Datasets 一起使用)
validation_steps=None, # 用于验证的步数(与 Datasets 一起使用)
validation_batch_size=None, # 验证数据的批次大小
**kwargs
)

关键参数:

  • x、y: 训练数据及其对应的标签/目标。
  • batch_size: 控制在模型权重更新前处理的样本数量。较小的批次可能导致更新更不稳定,但也可能有助于跳出局部最小值。较大的批次提供更稳定的梯度,但需要更多内存。
  • epochs: 一个 epoch 意味着模型已经完整地遍历了整个训练数据集一次。训练通常需要多个 epoch。
  • validation_data(或 validation_split): 对于监控模型在当前 epoch 训练过程中未见过的数据上的性能至关重要。有助于检测过拟合(当训练损失下降但验证损失增加时发生)。
  • callbacks: 允许自动化任务,例如保存最佳模型 (ModelCheckpoint)、在性能不再提升时提前停止训练 (EarlyStopping),或记录到 TensorBoard (TensorBoard)。

fit 方法返回一个 History 对象。此对象包含训练期间损失和指标值的记录,对于绘制学习曲线很有用。

# 假设 x_train, y_train, x_val, y_val 已准备好
# history = model.fit(x_train, y_train,
# batch_size=32,
# epochs=10,
# validation_data=(x_val, y_val),
# callbacks=[...])
# 访问训练历史
# print(history.history.keys()) # dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
# loss_curve = history.history['loss']
# accuracy_curve = history.history['accuracy']

示例:在 MNIST 数据集上训练一个 MLP

Section titled “示例:在 MNIST 数据集上训练一个 MLP”

让我们使用 MNIST 手写数字数据集,将编译和训练过程结合起来。

第 1 步:导入模块

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten # 添加 Flatten 以便后续潜在用于 CNN
from tensorflow.keras.optimizers import Adam # 使用 Adam 优化器
import numpy as np

第 2 步:加载和预处理数据

# 加载数据
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 预处理图像
# 为 MLP 将形状从 (60000, 28, 28) 转换为 (60000, 784)
x_train = x_train.reshape(60000, 784).astype('float32') / 255.0
x_test = x_test.reshape(10000, 784).astype('float32') / 255.0
# 如果使用 SparseCategoricalCrossentropy,则无需对标签进行 one-hot 编码
num_classes = 10
# y_train = tf.keras.utils.to_categorical(y_train, num_classes)
# y_test = tf.keras.utils.to_categorical(y_test, num_classes)

第 3 步:构建模型

model = Sequential([
tf.keras.Input(shape=(784,)), # 显式定义输入形状(可选方式)
Dense(512, activation='relu'),
Dropout(0.2),
Dense(512, activation='relu'),
Dropout(0.2),
Dense(num_classes, activation='softmax') # 10 个类别的输出层
])
model.summary()

第 4 步:编译模型

model.compile(loss='sparse_categorical_crossentropy', # 对整数标签使用稀疏版本
optimizer=Adam(learning_rate=0.001),
metrics=['accuracy'])

第 5 步:训练模型

batch_size = 128
epochs = 10 # 为更快演示而减少
print("\n训练模型...")
history = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test)) # 在此使用测试集作为验证数据
print("\n训练完成。")

第 6 步:评估(下一章介绍)

# score = model.evaluate(x_test, y_test, verbose=0)
# print('\n测试损失:', score[0])
# print('测试准确率:', score[1])

这个完整的示例展示了使用 tf.keras 从数据加载和预处理,到模型定义、编译和训练的整个工作流程。