1 概述
1.1创建模型的方法
在Keras框架中,创建模型主要有三种方式:
-
Sequential模型:这是一种非常直接的方法,它由一个简单的层列表组成。这种模型非常适合初学者,因为它的构建过程非常直观。然而,Sequential模型有一个限制,那就是它只能用于单输入和单输出的层堆叠。
-
Functional API:这是一种易于使用且功能齐全的API,它支持任意模型架构。对于大多数人和大多数用例来说,这是你应该选择的方式。Functional API是Keras的"工业级"模型,它允许你构建更复杂的模型,比如多输入多输出的模型。
-
模型子类化(Model subclassing):这种方式允许你从头开始实现一切,如果你有复杂的、非标准的研究用例,可以选择这种方式。模型子类化提供了最大的灵活性,但同时也需要更多的工作量和对Keras框架的深入理解。
每种方法都有其适用场景,选择合适的方法取决于你的具体需求和偏好。如果你正在开始学习Keras,可能会从Sequential模型开始,随着对框架的熟悉,你可能会转向Functional API来构建更复杂的模型。而当你需要进行高级研究或开发时,模型子类化可能是一个更好的选择。
1.2模型API概述
1.2.1Model 类
Model
类是Keras中用于构建和训练深度学习模型的基础类。它允许你定义模型的层、连接这些层、以及配置模型的训练过程。
- summary 方法
summary
方法用于打印模型的概述,包括每层的名称、输出形状、参数数量等。这对于理解和调试模型非常有用。
- get_layer 方法
get_layer
方法用于通过名称获取模型中的某一层。这在需要直接访问特定层或对其进行操作时非常有用。
1.2.2Sequential 类
Sequential
类是Model
的一个子类,用于构建线性堆叠的层(即每一层的输出都是下一层的输入)。它提供了一种简1.2.2单快捷的方式来定义模型。
add 方法
在Sequential
模型中,add
方法用于将新层添加到模型中。每次调用add
都会将新层添加到模型的最顶层。
pop 方法
pop
方法用于从Sequential
模型中移除顶层。这在需要修改模型结构时可能很有用。
1.2.3模型训练API
Keras提供了一系列用于模型训练的API。
compile
方法:配置模型的学习过程,包括优化器、损失函数和评估指标。fit
方法:用于训练模型。它接受训练数据、验证数据和其他训练参数,并迭代更新模型的权重以最小化损失。evaluate
方法:用于评估模型在测试集上的性能。它返回损失值和评估指标的值。predict
方法:使用模型对新的、未见过的数据进行预测。train_on_batch
方法:在单个批次上训练模型。这在需要更细粒度的控制训练过程时可能很有用。test_on_batch
方法:在单个批次上评估模型。predict_on_batch
方法:在单个批次上使用模型进行预测。
1.2.4保存与序列化
Keras提供了多种保存和加载模型的方法。
- 整个模型保存与加载:你可以将整个模型(包括其结构、权重和训练配置)保存为一个文件,并在需要时重新加载。
- 仅保存权重:如果你只需要保存和加载模型的权重,而不需要保存其结构或训练配置,你可以使用这种方法。
- 模型配置序列化:你可以将模型的配置(包括其结构和训练配置,但不包括权重)序列化为JSON或YAML格式的文件。这可以用于在不同的环境或机器之间共享模型的结构。
- 模型导出用于推理:Keras还支持将模型导出为TensorFlow SavedModel格式或TensorFlow Lite格式,以便在TensorFlow Serving或移动设备上进行推理。
序列化工具
Keras还提供了一些用于序列化和反序列化模型的辅助工具函数和类。这些工具可以帮助你在不同的环境或机器之间轻松地共享和重用模型。
2 模型类
典型的模型类如下
keras.Model()
2.1使用Functional API
使用“Functional API”时,程序员从输入开始,通过链式调用层来指定模型的前向传播,最后从输入和输出中创建模型。
这里是“Functional API”的一个简单概述,它允许你以一种更灵活和模块化的方式构建神经网络模型。相比于Sequential API(它只适用于层的线性堆叠),Functional API 允许程序员定义更复杂的模型,包括多输入、多输出以及共享层的模型。
在使用Functional API时,程序员可以:
- 使用
Input
类来定义输入张量的形状和类型。 - 调用层(如
Dense
,Conv2D
,MaxPooling2D
等)并将它们应用于输入张量。 - 通过链接多个层来定义前向传播路径。
- 使用
Model
类并传入输入和输出张量来实例化模型。
这样,程序员就可以通过编写一个类似于函数定义的前向传播过程来构建模型,并且可以很容易地重用和组合层来创建复杂的网络结构。
模型的输入和输出
inputs = keras.Input(shape=(37,))
x = keras.layers.Dense(32, activation="relu")(inputs)
outputs = keras.layers.Dense(5, activation="softmax")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
注意:仅支持字典、列表和元组的输入张量。不支持嵌套输入(例如列表的列表或字典的字典)。
使用中间张量也可以创建新的Functional API模型。这允许程序员快速提取模型的子组件。
在使用Keras的Functional API构建神经网络模型时,程序员需要定义输入和输出张量,并且这些输入必须是以字典、列表或元组的形式提供。然而,Keras不支持更复杂的嵌套结构作为输入,例如列表的列表或字典的字典。
此外,Functional API的一个特点是程序员可以通过中间张量(在模型构建过程中创建的张量)来创建新的模型或模型的一部分。这是通过将输入张量传递给一个或多个层,然后将这些层的输出作为新模型的输入或输出来实现的。这种方法允许程序员轻松地构建复杂的模型结构,并可以方便地提取和使用模型的子组件。
inputs = keras.Input(shape=(None, None, 3))
processed = keras.layers.RandomCrop(width=128, height=128)(inputs)
conv = keras.layers.Conv2D(filters=32, kernel_size=3)(processed)
pooling = keras.layers.GlobalAveragePooling2D()(conv)
feature = keras.layers.Dense(10)(pooling)
full_model = keras.Model(inputs, feature)
backbone = keras.Model(processed, conv)
activations = keras.Model(conv, feature)
请注意,骨干网络(backbone)和激活模型(activations)不是通过直接使用keras.Input
对象创建的,而是使用源自keras.Input
对象的张量来创建的。在内部,这些模型之间的层和权重是共享的,因此用户可以训练完整的模型(full_model),并使用骨干网络或激活模型来进行特征提取。模型的输入和输出也可以是张量的嵌套结构,并且创建的模型是标准的Functional API模型,支持所有现有的API。
在深度学习模型构建中,尤其是在迁移学习或特征提取的上下文中,我们经常使用预训练的模型作为骨干网络(backbone),并在其上添加自定义层来构建完整的模型。使用Keras的Functional API时,这些骨干网络和激活模型(即网络中的中间层)并不是通过直接定义输入层来创建的,而是使用从原始输入层(keras.Input
对象)流经网络并产生的中间张量来创建的。由于这些张量是在同一个计算图中定义的,因此它们引用的层和权重在骨干网络和激活模型中也是共享的。
这种设计使得用户能够:
- 训练完整的模型,该模型包括骨干网络和任何附加的层。
- 使用骨干网络或其中的特定层来进行特征提取,而不必重新训练整个模型。
同时,模型的输入和输出也可以是张量的复杂嵌套结构,这增加了模型设计的灵活性。无论输入输出的结构如何,使用Functional API创建的模型都是标准的,可以支持Keras提供的所有现有API和工具。
2.2继承Model类
通过继承Model
类,在这种情况下,程序员应该在__init__()
方法中定义自己层,并且程序员应该在call()
方法中实现模型的前向传播。
在Keras中,除了使用Functional API来构建模型外,程序员还可以通过继承Model
基类来定义自定义的模型。当程序员选择这种方式时,需要创建一个新的类,该类继承自tensorflow.keras.models.Model
(在TensorFlow 2.x中)或keras.models.Model
(在纯Keras或TensorFlow 1.x中)。
在自定义的模型类中,程序员需要在__init__()
方法中定义模型的层。这通常涉及创建Layer
类的实例,并将它们作为属性存储在模型类中。
然后,程序员需要实现call()
方法,该方法定义了模型的前向传播过程。当模型接收到输入数据并被调用时(例如,使用model(inputs)
或model.predict(data)
),call()
方法将被执行。在这个方法中,程序员应该编写将数据传递给各个层以及可能进行任何必要处理的代码,以计算模型的输出。
这种方法允许程序员更灵活地控制模型的结构和行为,因为它允许定义自己的初始化逻辑和自定义的前向传播过程。然而,这也需要更多的编程工作,因为它需要程序员从头开始构建模型的逻辑。
class MyModel(keras.Model):
def __init__(self):
super().__init__()
self.dense1 = keras.layers.Dense(32, activation="relu")
self.dense2 = keras.layers.Dense(5, activation="softmax")
def call(self, inputs):
x = self.dense1(inputs)
return self.dense2(x)
model = MyModel()
如果程序员继承Model
类,可以在call()
方法中可选地包含一个training
参数(布尔类型),可以使用它来指定在训练和推理时模型的不同行为。
在Keras中,当程序员继承Model
类并定义自己的模型时,call()
方法是用来实现模型的前向传播逻辑的。默认情况下,call()
方法只接受输入数据作为参数,并返回模型的输出。但是,在某些情况下,程序员可能希望在训练和推理时使用不同的行为。
为此,程序员可以在call()
方法中添加一个名为training
的布尔参数。这个参数会在模型被调用时自动传递,其值取决于当前的模式是训练模式还是推理模式(或称为评估模式)。在训练时,training
参数将被设置为True
,而在推理时,它将被设置为False
。
程序员可以在call()
方法内部根据training
参数的值来执行不同的逻辑。例如,可能在训练时使用dropout层来防止过拟合,但在推理时禁用dropout以获得更好的性能。通过检查training
参数的值,程序员可以有条件地应用dropout层,从而实现这种行为。
class MyModel(keras.Model):
def __init__(self):
super().__init__()
self.dense1 = keras.layers.Dense(32, activation="relu")
self.dense2 = keras.layers.Dense(5, activation="softmax")
self.dropout = keras.layers.Dropout(0.5)
def call(self, inputs, training=False):
x = self.dense1(inputs)
x = self.dropout(x, training=training)
return self.dense2(x)
model = MyModel()
一旦模型被创建,程序员可以使用model.compile()
方法来配置模型的损失函数和评估指标,使用model.fit()
方法来训练模型,或者使用model.predict()
方法来进行预测。
在Keras中,一旦定义了一个模型(无论是通过Functional API还是通过继承Model
类),程序员需要配置模型的训练过程。这通常包括指定损失函数(用于衡量模型预测与真实值之间的差异)、优化器(用于根据损失函数来更新模型的权重)以及评估指标(用于在训练和验证过程中跟踪模型的性能)。
程序员可以使用model.compile()
方法来完成这些配置。该方法接受损失函数、优化器和评估指标作为参数,并设置模型的内部状态以进行训练。
一旦模型被编译,就可以使用model.fit()
方法来训练模型了。该方法接受训练数据、验证数据(可选)、训练轮次(epochs)、批量大小(batch size)等参数,并迭代地更新模型的权重以最小化损失函数。
最后,程序员可以使用训练好的模型来进行预测。这可以通过调用model.predict()
方法来完成,该方法接受输入数据并返回模型的预测结果。这些预测结果可以用于评估模型的性能,或者用于在实际应用中做出决策。
2.3 使用Sequential类
使用Sequential
类时,keras.Sequential
是模型的一个特例,其中模型纯粹是由一系列单输入、单输出的层堆叠而成的。
在Keras中,Sequential
是一个简单的线性堆叠层的模型。当有一个明确的、顺序的层列表,并且每一层只有一个输入张量和一个输出张量时,使用Sequential
模型是最直接和最简便的方法。通过简单地按顺序添加层(比如通过add()
方法或直接在Sequential
类的初始化中传递层列表),你可以快速构建一个模型。
例如:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# 创建一个Sequential模型
model = Sequential()
# 添加一个Dense层,具有64个神经元和ReLU激活函数
model.add(Dense(64, activation='relu', input_shape=(input_dim,)))
# 再添加一个Dense层,具有10个神经元和softmax激活函数(用于分类)
model.add(Dense(10, activation='softmax'))
# 编译模型
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 训练模型
model.fit(x_train, y_train, epochs=5)
# 预测
predictions = model.predict(x_test)
在这个例子中,我们创建了一个Sequential
模型,并向其中添加了两个Dense
层。第一层有64个神经元,第二层有10个神经元。Sequential
模型会自动处理层之间的连接,因为每一层都假设其输入是前一层的输出(对于第一层,程序员需要指定input_shape
)。这使得模型构建过程变得非常简单和直观。
2.4 summary方法
summary
方法在 Keras 中通常用于打印模型的概述信息,包括每一层的名称、输出形状、参数数量等。因此,summary
方法的翻译可以是“摘要”或“概述”。
当程序员对一个 Keras 模型调用 summary()
方法时,它会返回一个表格形式的字符串,描述了模型的结构。这个信息对于了解模型如何工作、调整模型参数以及调试模型都非常有用。
例如:
Model.summary(
line_length=None,
positions=None,
print_fn=None,
expand_nested=False,
show_trainable=False,
layer_range=None,
)
参数:
line_length
:打印行的总长度(例如,设置此参数以适应不同终端窗口的大小)。positions
:日志元素在每行中的相对或绝对位置。如果没有提供,则默认为[0.3, 0.6, 0.70, 1.]
。默认为 None。print_fn
:要使用的打印函数。默认情况下,输出到标准输出。如果标准输出在你的环境中不起作用,可以改为print
函数。该函数将在摘要的每一行上被调用。你可以将其设置为自定义函数,以便捕获字符串摘要。expand_nested
:是否展开嵌套模型。默认为 False。show_trainable
:是否显示层是否可训练。默认为 False。layer_range
:一个包含两个字符串的列表或元组,表示开始层名称和结束层名称(都包含在内),指示在摘要中要打印的层范围。它也接受正则表达式模式而不是确切的名称。在这种情况下,开始谓词将是它与layer_range[0]
匹配的第一个元素,而结束谓词将是它与layer_range[1]
匹配的最后一个元素。默认为 None,表示考虑模型的所有层。
异常:
ValueError
:如果在模型构建之前调用summary()
方法。
2.5获取层get_layer 方法
get_layer
方法的翻译是“获取层”。
get_layer
方法通常用于从 Keras 模型中根据层的名称或索引检索特定的层。这是模型对象提供的一个实用方法,用于方便地访问模型内部的层。
例如,如果你有一个名为 my_model
的 Keras 模型,并且你知道其中有一个名为 dense_1
的层,你可以使用 my_model.get_layer('dense_1')
来获取这个层。同样,如果你知道你想要访问的层是模型中的第三个层(索引从0开始),你可以使用 my_model.get_layer(index=2)
来获取它。
需要注意的是,如果同时提供了名称和索引,则索引将优先。这意味着如果模型中有一个名为 dense_1
的层,并且它恰好也是第三个层,那么 my_model.get_layer(index=2)
将会返回该层,而不是 my_model.get_layer('dense_1')
的调用。
Model.get_layer(name=None, index=None)
根据层的名称(唯一)或索引检索层。
如果同时提供了名称和索引,则索引将优先。索引基于水平图遍历的顺序(从下到上)。
参数:
- name:字符串,层的名称。
- index:整数,层的索引。
返回:
一个层实例。
3Sequential类
Sequential
类,“顺序类”或“序列类”。
在 Keras 框架中,Sequential
类是一种简单的线性堆叠层的方式,用于构建模型。它允许用户按照顺序添加层,从而创建出一个简单的神经网络模型。由于 Sequential
模型的层是按照它们被添加的顺序进行堆叠的,因此它被称为“顺序”或“序列”模型。
keras.Sequential(layers=None, trainable=True, name=None)
3.1顺序堆叠特性
Sequential 将一系列层线性堆叠成一个模型(Model)。
model = keras.Sequential()
model.add(keras.Input(shape=(16,)))
model.add(keras.layers.Dense(8))
# Note that you can also omit the initial `Input`.
# In that case the model doesn't have any weights until the first call
# to a training/evaluation method (since it isn't yet built):
model = keras.Sequential()
model.add(keras.layers.Dense(8))
model.add(keras.layers.Dense(4))
# model.weights not created yet
# Whereas if you specify an `Input`, the model gets built
# continuously as you are adding layers:
model = keras.Sequential()
model.add(keras.Input(shape=(16,)))
model.add(keras.layers.Dense(8))
len(model.weights) # Returns "2"
# When using the delayed-build pattern (no input shape specified), you can
# choose to manually build your model by calling
# `build(batch_input_shape)`:
model = keras.Sequential()
model.add(keras.layers.Dense(8))
model.add(keras.layers.Dense(4))
model.build((None, 16))
len(model.weights) # Returns "4"
# Note that when using the delayed-build pattern (no input shape specified),
# the model gets built the first time you call `fit`, `eval`, or `predict`,
# or the first time you call the model on some input data.
model = keras.Sequential()
model.add(keras.layers.Dense(8))
model.add(keras.layers.Dense(1))
model.compile(optimizer='sgd', loss='mse')
# This builds the model for the first time:
model.fit(x, y, batch_size=32, epochs=10)
3.2add方法
在 Keras 的 Sequential
模型中,add
方法用于向模型中添加新的层。这个方法接受一个层实例作为参数,并将其添加到模型的末尾。例如,你可以使用 add
方法向 Sequential
模型中添加一个全连接层(Dense
)或一个卷积层(Conv2D
)等。
Sequential.add(layer, rebuild=True)
在层栈的顶部添加一个层实例。
参数:
- layer:层实例。
3.3pop方法
pop
方法是“弹出”或“移除”的含义。
在编程中,pop
方法通常用于从列表(或其他类似的数据结构)的末尾移除一个元素,并返回该元素的值。但在某些上下文中,如 Keras 的 Sequential
模型中,pop
方法可能用于移除模型中的最后一层。
在上面的代码中,pop
方法从 model
中移除了最顶层的层,并将该层的实例返回给 last_layer
变量。
Sequential.pop(rebuild=True)
4 模型训练API
Model training APIs 是“模型训练应用程序接口”或“模型训练API”。
“Model”指的是机器学习或深度学习中使用的模型,如神经网络模型。“Training”指的是使用数据来训练这个模型,使其能够学习并做出预测或决策的过程。“APIs”(Application Programming Interfaces)是应用程序编程接口,它定义了一系列规则和协议,使得不同的软件应用程序可以相互通信和交互。
Model training APIs 指的是keras用于训练和优化机器学习或深度学习模型的API接口,这些API通常提供了一组函数和方法,用于加载数据、配置模型参数、执行训练循环、评估模型性能等任务。通过使用这些API,开发者可以更加高效地构建和训练机器学习模型。
4.1compile方法
Model.compile(
optimizer="rmsprop",
loss=None,
loss_weights=None,
metrics=None,
weighted_metrics=None,
run_eagerly=False,
steps_per_execution=1,
jit_compile="auto",
auto_scale_loss=True,
)
参数说明:
optimizer
: 优化器的名称(字符串)或优化器实例。请参考 keras.optimizers。
loss
: 损失函数。可以是损失函数的名称(字符串),或者是 keras.losses.Loss 的实例。请参考 keras.losses。损失函数是一个可调用的函数,其签名是 loss = fn(y_true, y_pred)
,其中 y_true
是真实值(ground truth),y_pred
是模型的预测值。y_true
应该具有形状 (batch_size, d0, .. dN)
(对于稀疏损失函数如 sparse categorical crossentropy,它期望形状为 (batch_size, d0, .. dN-1)
的整数数组)。y_pred
应该具有形状 (batch_size, d0, .. dN)
。损失函数应该返回一个浮点张量。
loss_weights
: 可选的列表或字典,用于指定不同模型输出的损失贡献的权重(Python 浮点数)。模型将要最小化的损失值将是所有个体损失的加权和,权重由 loss_weights
系数确定。如果是一个列表,它应该与模型的输出有一一对应的关系。如果是一个字典,它应该映射输出名称(字符串)到权重系数。
metrics
: 在训练和测试期间,模型要评估的指标的列表。每个指标可以是内置函数的名称(字符串)、函数或 keras.metrics.Metric 的实例。请参考 keras.metrics。通常你会使用 metrics=['accuracy']
。一个函数是一个可调用的对象,其签名是 result = fn(y_true, y_pred)
。对于多输出模型的不同输出指定不同的指标,你也可以传递一个字典,如 metrics={'a':'accuracy', 'b':['accuracy', 'mse']}
。你还可以传递一个列表来指定每个输出的指标或指标列表,如 metrics=[['accuracy'], ['accuracy', 'mse']]
或 metrics=['accuracy', ['accuracy', 'mse']]
。当你传递字符串 ‘accuracy’ 或 ‘acc’ 时,我们会根据形状将其转换为 keras.metrics.BinaryAccuracy、keras.metrics.CategoricalAccuracy 或 keras.metrics.SparseCategoricalAccuracy 之一。对于字符串 “crossentropy” 和 “ce” 也会进行类似的转换。这里传递的指标在评估时不考虑样本权重;如果你希望应用样本权重,可以通过 weighted_metrics
参数来指定你的指标。
weighted_metrics
: 在训练和测试期间,用于根据 sample_weight
或 class_weight
评估和加权的指标列表。
run_eagerly
: 布尔值。如果为 True,则该模型的前向传递将永远不会被编译。建议在训练时将其设为 False(以获得最佳性能),并在调试时将其设为 True。
steps_per_execution
: 整数。在每次编译的函数调用期间运行的批次数量。在单个编译函数调用内部运行多个批次可以大大提高在 TPU 或具有较大 Python 开销的小型模型上的性能。最多,每次执行将运行一个完整的 epoch。如果传递的数字大于 epoch 的大小,则执行将被截断为 epoch 的大小。请注意,如果 steps_per_execution
设置为 N,则 Callback.on_batch_begin
和 Callback.on_batch_end
方法将仅在每 N 个批次(即每次编译函数执行之前/之后)被调用。PyTorch 后端不支持此参数。
jit_compile
: 布尔值或 “auto”。在编译模型时是否使用 XLA 编译。对于 jax 和 tensorflow 后端,jit_compile="auto"
将在模型支持时启用 XLA 编译,否则禁用。对于 torch 后端,“auto” 将默认为急切执行,而 jit_compile=True
将使用 torch.compile 并通过 “inductor” 后端运行。
auto_scale_loss
: 布尔值。如果为 True 并且模型的 dtype 策略是 “mixed_float16”,则传递的优化器将自动包装在 LossScaleOptimizer 中,后者将动态缩放损失以防止下溢。
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=1e-3),
loss=keras.losses.BinaryCrossentropy(),
metrics=[
keras.metrics.BinaryAccuracy(),
keras.metrics.FalseNegatives(),
],
)
4.2 fit方法
fit
方法:用于训练模型,通过迭代数据集中的样本并更新模型的内部状态(即权重)来最小化预定义的损失函数。
Model.fit(
x=None,
y=None,
batch_size=None,
epochs=1,
verbose="auto",
callbacks=None,
validation_split=0.0,
validation_data=None,
shuffle=True,
class_weight=None,
sample_weight=None,
initial_epoch=0,
steps_per_epoch=None,
validation_steps=None,
validation_batch_size=None,
validation_freq=1,
)
参数解释
x: 输入数据
- 可以是NumPy数组(或类似数组的对象),或者数组列表(如果模型有多个输入)。
- 可以是张量(tensor),或者张量列表(如果模型有多个输入)。
- 可以是一个字典,其键是输入名称,值是对应的数组/张量,如果模型有命名的输入。
- 可以是一个
tf.data.Dataset
对象,它应该返回一个元组,包含输入(inputs)和目标(targets),或者包含输入(inputs)、目标(targets)和样本权重(sample_weights)。 - 可以是一个
keras.utils.PyDataset
对象,它应该返回一个元组,包含输入(inputs)和目标(targets)或者包含输入(inputs)、目标(targets)和样本权重(sample_weights)。
y: 目标数据
- 与输入数据x类似,它可以是NumPy数组或后端原生张量。
- 如果x是一个数据集(dataset)、生成器(generator)或
keras.utils.PyDataset
实例,则不需要指定y(因为目标将从x中获取)。
batch_size: 批量大小
- 整数或None。每次梯度更新时使用的样本数量。如果未指定,batch_size将默认为32。
- 如果数据是以数据集、生成器或
keras.utils.PyDataset
实例的形式提供的,则不需要指定batch_size(因为它们会生成批次)。
epochs: 训练周期数
- 整数。训练模型的周期数。一个周期是指对整个x和y数据提供的一次迭代(除非将
steps_per_epoch
标志设置为非None)。 - 请注意,与
initial_epoch
结合使用时,epochs应被理解为“最终周期”。模型不是按照epochs指定的迭代次数进行训练的,而是直到达到索引为epochs的周期为止。
verbose
-
"auto"
, 0, 1, 或 2。控制日志显示模式。- 0 = 静默模式,不显示任何日志信息。
- 1 = 显示进度条。这是大多数情况下的默认值(“auto” 通常会变成 1)。
- 2 = 每个 epoch 输出一行日志。
注意:当日志被记录到文件时,进度条可能不是特别有用,因此在非交互式环境(例如生产环境)中,建议将
verbose
设置为 2。
callbacks
- 一个包含
keras.callbacks.Callback
实例的列表。这些回调会在训练过程中被应用。- Keras 提供了许多预定义的回调,例如
ModelCheckpoint
(用于保存模型检查点)、EarlyStopping
(用于提前停止训练以防止过拟合)等。 - 注意
keras.callbacks.ProgbarLogger
和keras.callbacks.History
回调是自动创建的,因此无需将它们传递给model.fit()
。keras.callbacks.ProgbarLogger
的创建基于verbose
参数的值。
- Keras 提供了许多预定义的回调,例如
validation_split
- 0 和 1 之间的浮点数。表示用作验证数据的训练数据的比例。
- 模型会将这个比例的训练数据单独留出,不会在训练时使用它,而是在每个 epoch 结束时在这个数据上评估损失和任何模型指标。
- 验证数据是从提供的 x 和 y 数据的最后几个样本中选择的,且在打乱数据之前进行。
- 如果 x 是一个数据集(dataset)、生成器(generator)或
keras.utils.PyDataset
实例,则不支持这个参数。 - 如果同时提供了
validation_data
和validation_split
,那么validation_data
将覆盖validation_split
。
这些参数进一步补充了 Keras fit
方法的用法,特别是关于验证数据和训练数据洗牌的部分。下面是这些参数的详细解释:
validation_data
-
在每个 epoch 结束时用于评估损失和任何模型指标的数据。模型不会在这个数据上进行训练。因此,请注意,使用
validation_split
或validation_data
提供的数据的验证损失不会受到如噪声和丢弃层等正则化层的影响。validation_data
会覆盖validation_split
。 -
可以是以下几种类型:
- NumPy 数组或张量的元组
(x_val, y_val)
。 - NumPy 数组的元组
(x_val, y_val, val_sample_weights)
,其中val_sample_weights
是样本权重。 tf.data.Dataset
对象。- Python 生成器或
keras.utils.PyDataset
,返回(inputs, targets)
或(inputs, targets, sample_weights)
。
- NumPy 数组或张量的元组
** shuffle**
- 布尔值,表示是否在每个 epoch 开始前对训练数据进行洗牌。当
x
是一个生成器或tf.data.Dataset
时,此参数将被忽略,因为生成器和数据集通常会在内部处理数据的洗牌。
class_weight
-
可选字典,将类索引(整数)映射到权重(浮点数)值,用于加权损失函数(仅在训练期间)。这对于告诉模型“更关注”来自表示不足的类的样本很有用。
-
当指定
class_weight
且目标y
的秩(rank)为 2 或更高时,y
必须进行独热编码(one-hot encoded),或者对于稀疏类标签,必须明确包含最终维度为 1。
例如,如果你有一个三分类问题,并且你希望第一个类的样本权重为 0.5,第二个类的样本权重为 1.0,第三个类的样本权重为 2.0,你可以设置 class_weight={0: 0.5, 1: 1.0, 2: 2.0}
。
sample_weight
-
可选的 NumPy 数组,用于训练样本的权重,仅用于加权损失函数(仅在训练期间)。你可以传递一个与输入样本长度相同的一维(1D)NumPy 数组(权重和样本之间的一对一映射),或者对于时序数据,你可以传递一个二维(2D)数组,其形状为
(samples, sequence_length)
,以便为每个样本的每个时间步应用不同的权重。 -
当
x
是一个数据集(dataset)、生成器(generator)或keras.utils.PyDataset
实例时,不支持此参数。相反,你应该将sample_weights
作为x
的第三个元素提供。 -
请注意,样本权重不适用于通过
compile()
方法的metrics
参数指定的指标。如果你想将样本权重应用于你的指标,你可以通过compile()
方法的weighted_metrics
参数来指定它们。
initial_epoch
- 整数,指定开始训练的 epoch(对于恢复先前的训练运行很有用)。例如,如果你已经训练了一个模型 10 个 epoch,并且你想从第 11 个 epoch 继续训练,你可以将
initial_epoch
设置为 10。
steps_per_epoch
- 整数或 None。在声明一个 epoch 结束并开始下一个 epoch 之前要执行的总步骤数(样本批次)。当使用输入张量(如后端原生张量)进行训练时,如果未指定
steps_per_epoch
,则默认值为数据集中的样本数除以批量大小,如果不能确定,则为 1。 - 如果
x
是一个tf.data.Dataset
,并且steps_per_epoch
为 None,则 epoch 将一直运行,直到输入数据集被完全消耗。 - 当传递一个无限重复的数据集时,必须指定
steps_per_epoch
参数。 - 如果
steps_per_epoch
设置为 -1,训练将在无限重复的数据集上无限期地运行。
validation_steps
- 仅当提供了
validation_data
时才相关。在每个 epoch 结束时执行验证时要执行的步骤数(样本批次)。 - 如果
validation_steps
为 None,则验证将一直运行,直到validation_data
数据集被完全消耗。 - 在无限重复的数据集的情况下,如果不指定
validation_steps
,验证将陷入无限循环。 - 如果指定了
validation_steps
并且只会消耗数据集的一部分,则每次 epoch 都会从数据集的开头开始评估。这确保了每次验证时都使用相同的验证样本。
validation_batch_size
- 整数或 None。验证时每个批次的样本数。如果未指定,将默认为
batch_size
。如果你的数据是以数据集或keras.utils.PyDataset
实例的形式提供的(因为它们会生成批次),则不应指定validation_batch_size
。
validation_freq
- 仅当提供了验证数据时相关。指定在执行新的验证运行之前要运行的训练 epoch 数,例如
validation_freq=2
表示每 2 个 epoch 运行一次验证。
迭代器类输入的解包行为
- 当向
fit
方法传递迭代器类输入(如tf.data.Dataset
或keras.utils.PyDataset
)时,这些迭代器通常会产生特征(x)、目标(y)和样本权重(sample_weight)。Keras 要求这些迭代器的输出是明确的。 - 迭代器应该返回一个长度为 1、2 或 3 的元组,其中可选的第二个和第三个元素将分别用于 y 和 sample_weight。如果提供了其他类型,它们将被包装在一个长度为 1 的元组中,从而将所有内容都视为 x。
- 当产生字典时,它们仍应遵守顶级元组结构,例如
({"x0": x0, "x1": x1}, y)
。Keras 不会尝试从单个字典的键中分离特征、目标和权重。 - 不支持的数据类型是具名元组(namedtuple)。原因是具名元组同时具有有序数据类型(元组)和映射数据类型(字典)的行为。因此,给定一个形式的具名元组
namedtuple("example_tuple", ["y", "x"])
,在解释值时,元素的顺序是否应该反转是不明确的。更糟糕的是,形式的元组namedtuple("other_tuple", ["x", "y", "z"])
,不清楚该元组是否打算被解包为 x、y 和 sample_weight,还是作为单个元素传递给 x。
返回值
一个 History
对象。它的 History.history
属性是一个记录,包含连续多个 epoch 的训练损失值和指标值,以及(如果适用)验证损失值和验证指标值。
4.3 evaluate方法
evaluate
方法是“评估”方法。
在机器学习和深度学习的上下文中,特别是在使用 Keras 这样的框架时,evaluate
方法通常用于在测试或验证数据集上评估模型的性能。它会返回模型在给定数据上的损失值和指标值(如准确率、精确度、召回率等),但不会更新模型的权重。这允许开发者了解模型在未见过的数据上的表现。
Model.evaluate(
x=None,
y=None,
batch_size=None,
verbose="auto",
sample_weight=None,
steps=None,
callbacks=None,
return_dict=False,
**kwargs
)
返回值
返回模型在测试模式下的损失值和指标值。
计算过程
计算是分批进行的(参见 batch_size
参数)。
参数
-
x
:输入数据。它可以是:- 一个 NumPy 数组(或类似数组),或数组列表(如果模型有多个输入)。
- 一个张量,或张量列表(如果模型有多个输入)。
- 一个字典,将输入名称映射到对应的数组/张量,如果模型有命名输入。
- 一个
tf.data.Dataset
。应该返回一个包含 (输入, 目标) 或 (输入, 目标, 样本权重) 的元组。 - 一个生成器或
keras.utils.PyDataset
,返回 (输入, 目标) 或 (输入, 目标, 样本权重)。
-
y
:目标数据。与输入数据x
类似,它可以是 NumPy 数组或后端原生张量。如果x
是一个tf.data.Dataset
或keras.utils.PyDataset
实例,则不应指定y
(因为目标将从迭代器/数据集中获取)。
batch_size
:整数或None。每批计算中的样本数。如果未指定,batch_size
将默认为32。如果你的数据是以数据集、生成器或keras.utils.PyDataset
实例的形式提供的(因为它们会生成批次),则不应指定batch_size
。
verbose
:“auto”、0、1或2。详细模式。0 = 静默模式,1 = 显示进度条,2 = 单行显示。在大多数情况下,“auto” 会变为1。请注意,当日志记录到文件时,进度条不是特别有用,因此当不是交互式运行(例如在生产环境中)时,建议使用 verbose=2
。默认为 “auto”。
sample_weight
:可选的NumPy数组,用于测试样本的权重,用于加权损失函数。你可以传递一个与输入样本长度相同的扁平(1D)NumPy数组(权重和样本之间的一一映射),或者在时序数据的情况下,你可以传递一个形状为 (样本数, 序列长度) 的2D数组,以便对每个样本的每个时间步应用不同的权重。当 x
是一个数据集时,不支持此参数,相反,应将样本权重作为 x
的第三个元素传递。
steps
:整数或None。在声明评估轮次完成之前的总步骤数(样本批次)。使用默认值None时将被忽略。如果 x
是一个 tf.data.Dataset
并且 steps
是None,那么评估将一直运行到数据集被耗尽为止。
callbacks
:keras.callbacks.Callback
实例的列表。在评估期间要应用的回调列表。
return_dict
:如果为True,损失和指标结果将作为字典返回,每个键都是指标的名称。如果为False,它们将作为列表返回。
返回值
如果模型具有单个输出且没有指标,则返回标量测试损失;如果模型具有多个输出和/或指标,则返回标量列表。model.metrics_names
属性将给出标量输出的显示标签。
4.4 predict方法
在机器学习和深度学习的上下文中,predict
方法通常用于使用训练好的模型对新的、未见过的数据进行预测。这个方法会输出模型对这些新数据点的预测结果。例如,在分类任务中,predict
方法可能会输出每个输入样本所属类别的预测标签;在回归任务中,它可能会输出每个输入样本的预测数值。
Model.predict(x, batch_size=None, verbose="auto", steps=None, callbacks=None)
为输入样本生成输出预测。
计算是分批进行的。这个方法是为了处理大量输入的批量处理而设计的。它并不打算用于在循环中迭代数据并一次处理少量输入的情况。
对于少量输入,如果它们可以放入一个批次中,直接使用 __call__()
方法进行更快的执行,例如 model(x)
,或者如果你有像 BatchNormalization
这样的层在推理时行为不同,可以使用 model(x, training=False)
。
参数:
x: 输入样本
它可以是:
- 一个 NumPy 数组(或类似数组的对象),或者数组的列表(如果模型有多个输入)。
- 一个张量,或者张量的列表(如果模型有多个输入)。
- 一个
tf.data.Dataset
。 - 一个
keras.utils.PyDataset
实例。
batch_size: 整数或 None。每批的样本数。如果未指定,则 batch_size
将默认为 32。如果你的数据是以数据集、生成器或 keras.utils.PyDataset
实例的形式提供的(因为它们会生成批次),则不应指定 batch_size
。
verbose: “auto”, 0, 1, 或 2。详细模式。0 = 静默模式,1 = 显示进度条,2 = 单行显示。“auto” 在大多数情况下会变为 1。请注意,当日志记录到文件时,进度条不是特别有用,因此在不进行交互式运行时(例如在生产环境中),建议使用 verbose=2
。默认为 “auto”。
steps: 在声明预测轮次完成之前的总步数(样本批次)。使用默认值 None 时将被忽略。如果 x
是一个 tf.data.Dataset
并且 steps
是 None,则 predict()
将一直运行直到输入数据集被耗尽。
callbacks: keras.callbacks.Callback
实例的列表。在预测期间要应用的回调列表。
返回值
预测结果的 NumPy 数组(或数组列表)。
4.5 train_on_batch方法
train_on_batch
方法即“按批次训练”。
这个方法用于在一个批次的数据上执行一次权重更新,而不是在整个数据集上。它对于在线学习(online learning)或当你想要更细粒度地控制训练过程时非常有用。train_on_batch
通常用于那些需要快速迭代或实时反馈的应用中。
使用 train_on_batch
时,程序员需要提供一个批次的输入数据(通常是 NumPy 数组)和对应的目标输出(如果是监督学习的话)。然后,模型会使用这些数据来执行一次前向和后向传递,并更新其权重。
Model.train_on_batch(
x, y=None, sample_weight=None, class_weight=None, return_dict=False
)
train_on_batch
方法在一个单一批次的数据上执行一次梯度更新。下面是该方法的参数和返回值的详细解释:
参数
x
: 输入数据。必须是类似数组的结构。y
: 目标数据(标签)。必须是类似数组的结构。sample_weight
: 可选参数,与x
长度相同的数组,包含每个样本应用于模型损失的权重。对于时序数据,可以传递一个形状为 (samples, sequence_length) 的二维数组,以在每个样本的每个时间步上应用不同的权重。class_weight
: 可选参数,一个字典,将类索引(整数)映射到权重(浮点数),用于在训练期间对来自该类的样本的模型损失进行加权。这可以用于告诉模型“更关注”来自表示不足的类的样本。当指定了class_weight
并且目标y
的秩(rank)为 2 或更大时,y
必须是一热编码的(one-hot encoded),或者对于稀疏类标签,必须包含一个显式的最终维度为 1。return_dict
: 如果为 True,则损失和度量结果将作为字典返回,其中每个键都是度量的名称。如果为 False,则它们将作为列表返回。
返回值
- 如果没有度量且
return_dict=False
,则返回一个标量损失值。 - 如果有度量且
return_dict=False
,则返回一个包含损失和度量值的列表。 - 如果
return_dict=True
,则返回一个包含度量名称和对应损失值的字典。
这个方法在训练神经网络时非常有用,特别是当你想要更精细地控制训练过程,或者当你需要在单个批次上快速评估模型性能时。通过调用 train_on_batch
,你可以在一个批次的数据上执行一次前向传递、计算损失、执行反向传递并更新模型的权重。
4.6 test_on_batch方法
test_on_batch
方法即“按批次测试”。
这个方法用于在一个批次的数据上评估模型的性能,但不会更新模型的权重。它返回该批次数据的损失值和任何已定义的度量值。这对于在训练过程中或者训练结束后快速检查模型在未见数据上的性能非常有用。
与 train_on_batch
不同,test_on_batch
仅执行前向传递,计算损失和度量值,但不会进行反向传递或更新模型权重。
使用 test_on_batch
时,你需要提供输入数据 x
和目标数据 y
(如果是监督学习)。你还可以选择性地提供 sample_weight
参数,以在评估损失时对不同样本应用不同的权重。
Model.test_on_batch(x, y=None, sample_weight=None, return_dict=False)
test_on_batch
方法的描述如下:
描述
在单个批次的样本上测试模型。
参数
x
: 输入数据。必须是类似数组的结构。y
: 目标数据(标签)。必须是类似数组的结构。sample_weight
: 可选参数,与x
长度相同的数组,包含每个样本应用于模型损失的权重。对于时序数据,可以传递一个形状为 (samples, sequence_length) 的二维数组,以在每个样本的每个时间步上应用不同的权重。return_dict
: 如果为 True,则损失和度量结果将作为字典返回,其中每个键都是度量的名称。如果为 False,则它们将作为列表返回。
返回值
- 如果没有度量且
return_dict=False
,则返回一个标量损失值。 - 如果有度量且
return_dict=False
,则返回一个包含损失和度量值的列表。 - 如果
return_dict=True
,则返回一个包含度量名称和对应损失值的字典。
用途
test_on_batch
方法在模型训练过程中或训练完成后用于快速评估模型在未见数据上的性能。与 train_on_batch
不同,test_on_batch
仅执行前向传递,计算损失和度量值,但不会进行反向传递或更新模型权重。这在需要快速迭代或实时反馈的场合非常有用。
4.7predict_on_batch方法
predict_on_batch
方法的翻译是“按批次预测”。
Model.predict_on_batch(x)
描述
该方法返回对单个批次样本的预测结果。
参数
x
: 输入数据。它必须是类似数组的结构。
返回值
- 预测结果的 NumPy 数组(或数组列表,如果模型有多个输出)。
用途
predict_on_batch
方法在 Keras(或其他深度学习框架)中常用于对一批输入数据执行前向传递,并返回模型对这些数据的预测结果。这个方法不会进行任何梯度计算或更新模型权重,因此它非常适合用于快速预测或模型评估。