Keras 工作流程详解:从入门到精通的三种建模方法
Keras API 采用渐进式呈现复杂性的设计原则:既易于上手,又能处理复杂用例。无论你是初学者还是专家,都可以使用相同的工具,只是使用方式不同。
构建Keras 模型的三种方法
Keras 提供了三种构建模型的方法,满足不同层次的需求:
-
序贯模型:最简单的API,仅限于层的简单堆叠 -
函数式 API:最常用的API,在可用性和灵活性之间找到平衡 -
模型子类化:最底层的选项,提供完全的控制权
一、序贯模型:最简单的方法
基本用法
from tensorflow import keras
from tensorflow.keras import layers
# 方法1:直接传入层列表
model = keras.Sequential([
layers.Dense(64, activation="relu"),
layers.Dense(10, activation="softmax")
])
# 方法2:逐步添加层
model = keras.Sequential()
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(10, activation="softmax"))
重要特性:延迟构建
Keras 模型在第一次调用时才会构建权重:
# 初始时模型没有权重
model.weights # 返回空列表
# 第一次调用后构建权重
import numpy as np
x = np.random.random((1, 3))
y = model(x)
print(model.weights) # 现在有权重了
提前声明输入形状
model = keras.Sequential()
model.add(keras.Input(shape=(3,))) # 提前声明输入形状
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(10, activation="softmax"))
# 现在可以随时查看模型概述
model.summary()
二、函数式API:最常用的方法
函数式API 就像拼乐高积木,可以构建复杂的模型结构。
简单示例
# 定义输入
inputs = keras.Input(shape=(3,), name="my_input")
# 通过调用层来构建网络
features = layers.Dense(64, activation="relu")(inputs)
outputs = layers.Dense(10, activation="softmax")(features)
# 创建模型
model = keras.Model(inputs=inputs, outputs=outputs)
多输入、多输出模型
函数式API 的真正威力在于构建复杂模型:
# 定义三个输入
title = keras.Input(shape=(10000,), name="title") # 工单标题
text_body = keras.Input(shape=(10000,), name="text_body") # 工单正文
tags = keras.Input(shape=(100,), name="tags") # 用户标签
# 特征处理
title_features = layers.Dense(64, activation="relu")(title)
text_body_features = layers.Dense(64, activation="relu")(text_body)
# 合并特征
features = layers.concatenate([title_features, text_body_features, tags])
# 定义两个输出
priority = layers.Dense(1, activation="sigmoid", name="priority")(features) # 优先级分数
department = layers.Dense(4, activation="softmax", name="department")(features) # 部门分类
# 创建多输入多输出模型
model = keras.Model(
inputs=[title, text_body, tags],
outputs=[priority, department]
)
模型可视化
# 绘制模型结构图
keras.utils.plot_model(model, "ticket_classifier.png")
# 显示形状信息
keras.utils.plot_model(
model,
"ticket_classifier_with_shape_info.png",
show_shapes=True
)
训练多输入多输出模型
# 编译模型
model.compile(optimizer="rmsprop",
loss={"priority": "mean_squared_error",
"department": "categorical_crossentropy"},
metrics={"priority": ["mean_absolute_error"],
"department": ["accuracy"]})
# 准备模拟数据
num_samples = 1000
title_data = np.random.random((num_samples, 10000))
text_body_data = np.random.random((num_samples, 10000))
tags_data = np.random.random((num_samples, 100))
priority_data = np.random.random((num_samples, 1))
department_data = np.random.random((num_samples, 4))
# 训练模型
model.fit(
{"title": title_data, "text_body": text_body_data, "tags": tags_data},
{"priority": priority_data, "department": department_data},
epochs=1,
batch_size=32
)
特征提取和模型复用
函数式模型可以轻松提取和复用中间特征:
# 提取中间层输出
features = model.layers[4].output # 获取连接层后的特征
# 添加新输出
difficulty = layers.Dense(3, activation="softmax", name="difficulty")(features)
# 创建新模型
new_model = keras.Model(
inputs=[title, text_body, tags],
outputs=[priority, department, difficulty]
)
三、模型子类化:完全控制
对于特殊需求,可以使用模型子类化:
classCustomerTicketModel(keras.Model):
def__init__(self, num_departments):
super().__init__()
# 定义子层
self.concat_layer = layers.Concatenate()
self.mixing_layer = layers.Dense(64, activation="relu")
self.priority_scorer = layers.Dense(1, activation="sigmoid")
self.department_classifier = layers.Dense(
num_departments, activation="softmax")
defcall(self, inputs):
# 定义前向传播
title = inputs["title"]
text_body = inputs["text_body"]
tags = inputs["tags"]
# 混合特征
features = self.concat_layer([title, text_body, tags])
features = self.mixing_layer(features)
# 生成输出
priority = self.priority_scorer(features)
department = self.department_classifier(features)
return priority, department
# 使用自定义模型
model = CustomerTicketModel(num_departments=4)
priority, department = model({
"title": title_data,
"text_body": text_body_data,
"tags": tags_data
})
四、混合使用不同组件
Keras 的各种建模方法可以混合使用:
# 在函数式模型中使用子类化层
classClassifier(keras.Model):
def__init__(self, num_classes=2):
super().__init__()
if num_classes == 2:
num_units = 1
activation = "sigmoid"
else:
num_units = num_classes
activation = "softmax"
self.dense = layers.Dense(num_units, activation=activation)
defcall(self, inputs):
return self.dense(inputs)
# 在函数式流程中使用自定义模型
inputs = keras.Input(shape=(3,))
features = layers.Dense(64, activation="relu")(inputs)
outputs = Classifier(num_classes=10)(features)
model = keras.Model(inputs=inputs, outputs=outputs)
选择合适的方法
-
序贯模型:简单的层堆叠 -
函数式API:大多数情况下的最佳选择,支持复杂拓扑结构 -
模型子类化:需要完全控制时的选择
推荐:优先使用函数式API,它在易用性和灵活性之间达到了最佳平衡,同时支持模型可视化和特征提取。
无论选择哪种方法,Keras 都提供了一致的工作流程,让你能够从简单开始,逐步应对更复杂的挑战。

