前言:
Keras API
的设计原则是
渐进式呈现复杂性
(
progressive disclosure of complexity
):易于
上手,同时又可以处理非常复杂的用例,只需逐步渐进式学习。简单的工作流程应该简单易懂,
同时还有高级的工作流程:无论你的问题多么罕见、多么复杂,应该都有一条清晰的解决路径。
这条路径是建立在简单工作流程的基础之上的。也就是说,你从初学者成长为专家,可以一直
使用相同的工具,只是使用方式不同。
因此,
Keras
没有唯一“正确”的使用方式。相反,
Keras
提供了
一系列工作流程
,既有非
常简单的工作流程,也有非常灵活的工作流程。
构建 Keras 模型的不同方法:
一、序贯模型(sequential model):这是最容易理解的 API。它本质上是 Python 列表,仅限 于层的简单堆叠。
#导入一些相关模块
from tensorflow import keras
from tensorflow.keras import layers
#方法一:Sequential 类
model = keras.Sequential([
layers.Dense(64, activation="relu"),
layers.Dense(10, activation="softmax")
])
#方法二:请注意,还可以使用 add() 方法逐步构建相同的模型,它类似于Python 列表的 append() 方法。
model = keras.Sequential()
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(10, activation="softmax"))
二、函数式 API(functional API):它专注于类似图的模型结构。它在可用性和灵活性之间找 到了很好的平衡点,因此是构建模型最常用的 API。
序贯模型易于使用,但适用范围非常有限:
它只能表示具有单一输入和单一输出的模型
,
按顺序逐层进行处理。我们在实践中经常会遇到其他类型的模型,
比如多输入模型(如图像及
其元数据)、多输出模型(预测数据的不同方面)或具有非线性拓扑结构的模型。
在这种情况下,你可以使用函数式 API 构建模型。
#带有两个 Dense 层的简单函数式模型
inputs=keras.Input(shape=(3,),name="my_input")#每个样本的形状为 (3,)
features=layers.Dense(64,activation="relu")(inputs)#创建了一个层,并在输入上调用该层。
outputs=layers.Dense(10,activation="softmax")(features)
model=keras.Model(inputs=inputs,outputs=outputs)#我们在 Model 构造函数中指定输入和输出,将模型实例化
#多输入、多输出的函数式模型
vocabulary_size=10000
num_tags=100
num_departments=4
#定义模型的输入
title=keras.Input(shape=(vocabulary_size,),name="title")
text_body=keras.Input(shape=(vocabulary_size,),name="text_body")
tags=keras.Input(shape=(num_tags,),name="tags")
#%%
features=layers.Concatenate()([title,text_body,tags])#通过拼接将输入特征组合成张量features
features=layers.Dense(64,activation="relu")(features)#利用中间层,将输入特征重组
priority=layers.Dense(1,activation="sigmoid",name="priority")(features)
department=layers.Dense(
num_departments,activation="softmax",name="department"
)(features)#定义模型输出
#%%
model=keras.Model(inputs=[title,text_body,tags],outputs=[priority,department])#通过指定输入和输出来创建模型
三、模型子类化(model subclassing):它是一个底层选项,你可以从头开始自己编写所有内容。 如果你想控制每一个小细节,那么它是理想的选择。但是这样就无法使用 Keras 内置的 许多特性,而且更容易犯错误。
假设你要构建一个系统,按优先级对客户支持工单进行排序,并将工单转给相应的部门。
这个模型有 3 个输入:
工单标题(文本输入)
工单的文本正文(文本输入)
用户添加的标签(分类输入,假定为 one-hot 编码)
我们可以将文本输入编码为由 1 和 0 组成的数组,数组大小为 vocabulary_size
模型还有 2 个输出:
工单的优先级分数,它是介于 0 和 1 之间的标量(sigmoid 输出)
应处理工单的部门(对所有部门做 softmax)
利用函数式 API,仅凭几行代码就可以构建这个模型
class CustomerTicketModel(keras.Model):
def __init__(self,num_departments):
super().__init__()#不要忘记调用 super()构造函数!
#在构造函数中定义子层
self.concat_layer=layers.Concatenate()
self.mixing_layer=layers.Dense(63,activation="relu")
self.priority_scorer=layers.Dense(1,activation="sigmoid")
self.department_classifier=layers.Dense(num_departments,activation="softmax")
def call(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})