Keras 是一个用于构建和训练深度学习模型的高阶API。它可用于快速设计原型、高级研究和生产,具有以下三个主要优势:
Keras 具有针对常见用例做出优化的简单而一致的界面。它可针对用户错误提供切实可行的清晰反馈。
将可配置的构造块连接在一起就可以构建 Keras 模型,并且几乎不受限制。
可以编写自定义构造块以表达新的研究创意,并且可以创建新层、损失函数并开发先进的模型。
tf.keras
是 TensorFlow 对 Keras API 规范的实现。这是一个用于构建和训练模型的高阶 API,包含对 TensorFlow 特定功能(例如eager execution、tf.data
管道和 Estimators)的顶级支持。 tf.keras
使 TensorFlow 更易于使用,并且不会牺牲灵活性和性能。
首先,导入 tf.keras
以设置 TensorFlow 程序:
x1from __future__ import absolute_import, division, print_function, unicode_literals
2
3import tensorflow as tf
4
5from tensorflow import keras
tf.keras
可以运行任何与 Keras 兼容的代码,但请注意:
tf.keras
版本可能与 PyPI 中的最新 keras 版本不同。请查看 tf.keras.version
。tf.keras
默认采用检查点格式。请传递 save_format='h5'
以使用 HDF5。在 Keras 中,您可以通过组合层来构建模型。模型(通常)是由层构成的图。最常见的模型类型是层的堆叠:tf.keras.Sequential
模型。
要构建一个简单的全连接网络(即多层感知器),请运行以下代码:
xxxxxxxxxx
91from tensorflow.keras import layers
2
3model = tf.keras.Sequential()
4# 向模型添加一个64单元的密集连接层:
5model.add(layers.Dense(64, activation='relu'))
6# 加上另一个:
7model.add(layers.Dense(64, activation='relu'))
8# 添加一个包含10个输出单位的softmax层:
9model.add(layers.Dense(10, activation='softmax'))
您可以找到有关如何使用Sequential模型的完整简短示例 here.
要了解如何构建比Sequential模型更高级的模型,请参阅:
我们可以使用很多 tf.keras.layers
,它们具有一些相同的构造函数参数:
activation
:设置层的激活函数。此参数由内置函数的名称指定,或指定为可调用对象。默认情况下,系统不会应用任何激活函数。kernel_initializer
和 bias_initializer
:创建层权重(核和偏差)的初始化方案。此参数是一个名称或可调用对象,默认为 "Glorot uniform" 初始化器。kernel_regularizer
和 bias_regularizer
:应用层权重(核和偏差)的正则化方案,例如 L1 或 L2 正则化。默认情况下,系统不会应用正则化函数。以下代码使用构造函数参数实例化 tf.keras.layers. Dense
层:
xxxxxxxxxx
161# 创建一个sigmoid层:
2layers.Dense(64, activation='sigmoid')
3# 或者使用下面的代码创建:
4layers.Dense(64, activation=tf.keras.activations.sigmoid)
5
6# 将具有因子0.01的L1正则化的线性层应用于核矩阵:
7layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01))
8
9# 将L2正则化系数为0.01的线性层应用于偏置向量:
10layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01))
11
12# 一个内核初始化为随机正交矩阵的线性层:
13layers.Dense(64, kernel_initializer='orthogonal')
14
15# 偏置矢量初始化为2.0s的线性层:
16layers.Dense(64, bias_initializer=tf.keras.initializers.Constant(2.0))
构建好模型后,通过调用 compile
方法配置该模型的学习流程:
xxxxxxxxxx
111model = tf.keras.Sequential([
2# 向模型添加一个64单元的密集连接层:
3layers.Dense(64, activation='relu', input_shape=(32,)),
4# 加上另一个:
5layers.Dense(64, activation='relu'),
6# 添加具有10个输出单位的softmax层:
7layers.Dense(10, activation='softmax')])
8
9model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
10 loss='categorical_crossentropy',
11 metrics=['accuracy'])
tf.keras.Model.compile
采用三个重要参数:
optimizer
:此对象会指定训练过程。从tf.keras.optimizers
模块向其传递优化器实例,例如 tf.keras.optimizers.Adam
、tf.keras.optimizers.SGD
。如果您只想使用默认参数,还可以通过字符串指定优化器,例如'adam'或'sgd'。loss
:要在优化期间最小化的函数。常见选择包括均方误差 (mse
)、categorical_crossentropy
和 binary_crossentropy
。损失函数由名称或通过从 tf.keras.losses
模块传递可调用对象来指定。metrics
:用于监控训练。它们是 tf.keras.metrics
模块中的字符串名称或可调用对象。run_eagerly=True
作为参数进行编译。以下代码展示了配置模型以进行训练的几个示例:
xxxxxxxxxx
91# 配置均方误差回归模型。
2model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
3 loss='mse', # 均方误差
4 metrics=['mae']) # 平均绝对误差
5
6# 为分类分类配置一个模型
7model.compile(optimizer=tf.keras.optimizers.RMSprop(0.01),
8 loss=tf.keras.losses.CategoricalCrossentropy(),
9 metrics=[tf.keras.metrics.CategoricalAccuracy()])
对于小型数据集,请使用内存中的NumPy数组训练和评估模型。使用 fit 方法使模型与训练数据“拟合”:
xxxxxxxxxx
61import numpy as np
2
3data = np.random.random((1000, 32))
4labels = np.random.random((1000, 10))
5
6model.fit(data, labels, epochs=10, batch_size=32)
xxxxxxxxxx
31...
2Epoch 10/10
31000/1000 [==============================] - 0s 82us/sample - loss: 11.4075 - categorical_accuracy: 0.1690
tf.keras.Model.fit
采用三个重要参数:
epochs
:以周期为单位进行训练。一个周期是对整个输入数据的一次迭代(以较小的批次完成迭代)。batch_size
:当传递 NumPy 数据时,模型将数据分成较小的批次,并在训练期间迭代这些批次。此整数指定每个批次的大小。请注意,如果样本总数不能被批次大小整除,则最后一个批次可能更小。validation_data
:在对模型进行原型设计时,您需要轻松监控该模型在某些验证数据上达到的效果。传递此参数(输入和标签元组)可以让该模型在每个周期结束时以推理模式显示所传递数据的损失和指标。下面是使用 validation_data
的示例:
xxxxxxxxxx
101import numpy as np
2
3data = np.random.random((1000, 32))
4labels = np.random.random((1000, 10))
5
6val_data = np.random.random((100, 32))
7val_labels = np.random.random((100, 10))
8
9model.fit(data, labels, epochs=10, batch_size=32,
10 validation_data=(val_data, val_labels))
xxxxxxxxxx
51Train on 1000 samples, validate on 100 samples
2...
3Epoch 10/10
41000/1000 [==============================] - 0s 93us/sample - loss: 11.5019 - categorical_accuracy: 0.1220 - val_loss: 11.5879 - val_categorical_accuracy: 0.0800
5<tensorflow.python.keras.callbacks.History at 0x7fe0642970b8>
使用 Datasets API 可扩展为大型数据集或多设备训练。将 tf.data.Dataset
实例传递到 fit
方法:
xxxxxxxxxx
61# 实例化玩具数据集实例:
2dataset = tf.data.Dataset.from_tensor_slices((data, labels))
3dataset = dataset.batch(32)
4
5# 在数据集上调用`fit`时,不要忘记指定`steps_per_epoch`。
6model.fit(dataset, epochs=10, steps_per_epoch=30)
输出:
xxxxxxxxxx
21Epoch 1/10
230/30 [==============================] - 0s 7ms/step - loss: 11.4902 - categorical_accuracy: 0.1094
在上方代码中,fit
方法使用了 steps_per_epoch
参数(表示模型在进入下一个周期之前运行的训练步数)。由于 Dataset
会生成批次数据,因此该代码段不需要 batch_size
。
数据集也可用于验证:
xxxxxxxxxx
81dataset = tf.data.Dataset.from_tensor_slices((data, labels))
2dataset = dataset.batch(32)
3
4val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_labels))
5val_dataset = val_dataset.batch(32)
6
7model.fit(dataset, epochs=10,
8 validation_data=val_dataset)
xxxxxxxxxx
51...
2Epoch 10/10
332/32 [==============================] - 0s 4ms/step - loss: 11.4778 - categorical_accuracy: 0.1560 - val_loss: 11.6653 - val_categorical_accuracy: 0.1300
4
5<tensorflow.python.keras.callbacks.History at 0x7fdfd8329d30>
tf.keras.Model.evaluate
和tf.keras.Model.predict
方法可以使用NumPy数据和tf.data.Dataset
。
要评估所提供数据的推理模式损失和指标,请运行以下代码:
xxxxxxxxxx
61data = np.random.random((1000, 32))
2labels = np.random.random((1000, 10))
3
4model.evaluate(data, labels, batch_size=32)
5
6model.evaluate(dataset, steps=30)
xxxxxxxxxx
411000/1000 [==============================] - 0s 72us/sample - loss: 11.5580 - categorical_accuracy: 0.0960
230/30 [==============================] - 0s 2ms/step - loss: 11.4651 - categorical_accuracy: 0.1594
3
4[11.465100129445394, 0.159375]
要在所提供数据(采用 NumPy 数组形式)的推理中预测最后一层的输出,请运行以下代码:
xxxxxxxxxx
21result = model.predict(data, batch_size=32)
2print(result.shape)
xxxxxxxxxx
11(1000, 10)
有关训练和评估的完整指南,包括如何从头开始编写自定义训练循环,请参阅训练和评估指南。
tf.keras.Sequential
模型是层的简单堆叠,无法表示任意模型。使用 Keras 函数式 API 可以构建复杂的模型拓扑,例如:
使用函数式 API 构建的模型具有以下特征:
tf.keras.Model
实例。Sequential
模型一样。以下示例使用函数式 API 构建一个简单的全连接网络:
xxxxxxxxxx
61inputs = tf.keras.Input(shape=(32,)) # 返回输入占位符
2
3# 层实例可在张量上调用,并返回张量。
4x = layers.Dense(64, activation='relu')(inputs)
5x = layers.Dense(64, activation='relu')(x)
6predictions = layers.Dense(10, activation='softmax')(x)
在给定输入和输出的情况下实例化模型。
xxxxxxxxxx
91model = tf.keras.Model(inputs=inputs, outputs=predictions)
2
3# compile步骤指定训练配置
4model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
5 loss='categorical_crossentropy',
6 metrics=['accuracy'])
7
8# 训练5个周期
9model.fit(data, labels, batch_size=32, epochs=5)
xxxxxxxxxx
51...
2Epoch 5/5
31000/1000 [==============================] - 0s 81us/sample - loss: 11.4819 - accuracy: 0.1270
4
5<tensorflow.python.keras.callbacks.History at 0x7fdfd820b898>
通过对 tf.keras.Model
进行子类化,并定义您自己的前向传播来构建完全可自定义的模型。在__init__
方法中创建层并将它们设置为类实例的属性。在 call
方法中定义前向传播。
在启用 eager execution 时,模型子类化特别有用,因为可以强制写入前向传播。
注意:为了确保正向传递总是强制运行,你必须在调用超级构造函数时设置dynamic = True
要点:针对作业使用正确的 API。虽然模型子类化较为灵活,但代价是复杂性更高且用户出错率更高。如果可能,请首选函数式 API。
以下示例展示了使用自定义前向传播进行子类化的 tf.keras.Model
,该传递不必强制运行:
xxxxxxxxxx
141class MyModel(tf.keras.Model):
2
3 def __init__(self, num_classes=10):
4 super(MyModel, self).__init__(name='my_model')
5 self.num_classes = num_classes
6 # 在此处定义层。.
7 self.dense_1 = layers.Dense(32, activation='relu')
8 self.dense_2 = layers.Dense(num_classes, activation='sigmoid')
9
10 def call(self, inputs):
11 # 在这里定义你的前向传播
12 # 使用之前定义的层(在`__init__`中)
13 x = self.dense_1(inputs)
14 return self.dense_2(x)
实例化新模型类:
xxxxxxxxxx
91model = MyModel(num_classes=10)
2
3# The compile step specifies the training configuration.
4model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
5 loss='categorical_crossentropy',
6 metrics=['accuracy'])
7
8# 训练5个周期
9model.fit(data, labels, batch_size=32, epochs=5)
xxxxxxxxxx
21...
2Epoch 5/5 1000/1000 [==============================] - 0s 74us/sample - loss: 11.4954 - accuracy: 0.1110
通过继承 tf.keras.layers.Layer
并实现以下方法来创建自定义层:
__init__
: (可选)定义此层要使用的子层build
: 创建层的权重。使用 add_weight
方法添加权重。call
: 定义前向传播。get_config
方法和 from_config
类方法序列化层。下面是一个自定义层的示例,它使用核矩阵实现输入的matmul
:
xxxxxxxxxx
241class MyLayer(layers.Layer):
2
3 def __init__(self, output_dim, **kwargs):
4 self.output_dim = output_dim
5 super(MyLayer, self).__init__(**kwargs)
6
7 def build(self, input_shape):
8 # Create a trainable weight variable for this layer.
9 self.kernel = self.add_weight(name='kernel',
10 shape=(input_shape[1], self.output_dim),
11 initializer='uniform',
12 trainable=True)
13
14 def call(self, inputs):
15 return tf.matmul(inputs, self.kernel)
16
17 def get_config(self):
18 base_config = super(MyLayer, self).get_config()
19 base_config['output_dim'] = self.output_dim
20 return base_config
21
22
23 def from_config(cls, config):
24 return cls(**config)
使用自定义层创建模型:
xxxxxxxxxx
111model = tf.keras.Sequential([
2 MyLayer(10),
3 layers.Activation('softmax')])
4
5# 训练配置
6model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
7 loss='categorical_crossentropy',
8 metrics=['accuracy'])
9
10# 训练5个周期
11model.fit(data, labels, batch_size=32, epochs=5)
了解有关从头开始创建新层和模型的更多信息,在从头开始编写层和模型指南。
回调是传递给模型的对象,用于在训练期间自定义该模型并扩展其行为。您可以编写自定义回调,也可以使用包含以下方法的内置 tf.keras.callbacks
:
tf.keras.callbacks.ModelCheckpoint
: 定期保存模型的检查点。tf.keras.callbacks.LearningRateScheduler
: 动态更改学习速率。tf.keras.callbacks.EarlyStopping
:在验证效果不再改进时中断训练。tf.keras.callbacks.TensorBoard
: 使用 TensorBoard 监控模型的行为。要使用 tf.keras.callbacks.Callback
,请将其传递给模型的 fit
方法:
xxxxxxxxxx
81callbacks = [
2 # 如果`val_loss`在2个以上的周期内停止改进,则进行中断训练
3 tf.keras.callbacks.EarlyStopping(patience=2, monitor='val_loss'),
4 # 将TensorBoard日志写入`./logs`目录
5 tf.keras.callbacks.TensorBoard(log_dir='./logs')
6]
7model.fit(data, labels, batch_size=32, epochs=5, callbacks=callbacks,
8 validation_data=(val_data, val_labels))
xxxxxxxxxx
31Train on 1000 samples, validate on 100 samples
2...
3Epoch 5/5 1000/1000 [==============================] - 0s 76us/sample - loss: 11.4813 - accuracy: 0.1190 - val_loss: 11.5753 - val_accuracy: 0.1100 <tensorflow.python.keras.callbacks.History at 0x7fdfd12e7080>
使用 tf.keras.Model.save_weights
保存并加载模型的权重:
xxxxxxxxxx
71model = tf.keras.Sequential([
2layers.Dense(64, activation='relu', input_shape=(32,)),
3layers.Dense(10, activation='softmax')])
4
5model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
6 loss='categorical_crossentropy',
7 metrics=['accuracy'])
xxxxxxxxxx
51# 将权重保存到TensorFlow检查点文件
2model.save_weights('./weights/my_model')
3
4# 恢复模型的状态,这需要具有相同架构的模型。
5model.load_weights('./weights/my_model')
默认情况下,会以 TensorFlow 检查点文件格式保存模型的权重。权重也可以另存为 Keras HDF5 格式(Keras 多后端实现的默认格式):
xxxxxxxxxx
51# 将权重保存到HDF5文件
2model.save_weights('my_model.h5', save_format='h5')
3
4# 恢复模型的状态
5model.load_weights('my_model.h5')
可以保存模型的配置,此操作会对模型架构(不含任何权重)进行序列化。即使没有定义原始模型的代码,保存的配置也可以重新创建并初始化相同的模型。Keras 支持 JSON 和 YAML 序列化格式:
xxxxxxxxxx
31# 将模型序列化为JSON格式
2json_string = model.to_json()
3json_string
xxxxxxxxxx
11'{"class_name": "Sequential", "config": {"layers": [{"class_name": "Dense", "config": {"units": 64, "activity_regularizer": null, "dtype": "float32",....... "backend": "tensorflow", "keras_version": "2.2.4-tf"}'
xxxxxxxxxx
31import json
2import pprint
3pprint.pprint(json.loads(json_string))
xxxxxxxxxx
11{'backend': 'tensorflow', 'class_name': 'Sequential', 'config': {'layers': [{'class_name': 'Dense', 'config': {'activation': 'relu', 'activity_regularizer': None, '......'keras_version': '2.2.4-tf'}
更多运行的输出内容请看英文版https://tensorflow.google.cn/beta/guide/keras/overview
从 json 重新创建模型(刚刚初始化)。
xxxxxxxxxx
11fresh_model = tf.keras.models.model_from_json(json_string)
将模型序列化为YAML格式,要求您在导入TensorFlow之前安装pyyaml(命令:pip install -q pyyaml
):
xxxxxxxxxx
21yaml_string = model.to_yaml()
2print(yaml_string)
从YAML重新创建模型:
xxxxxxxxxx
11fresh_model = tf.keras.models.model_from_yaml(yaml_string)
注意:子类化模型不可序列化,因为它们的架构由call
方法正文中的 Python 代码定义。
整个模型可以保存到一个文件中,其中包含权重值、模型配置乃至优化器配置。这样,您就可以对模型设置检查点并稍后从完全相同的状态继续训练,而无需访问原始代码。
xxxxxxxxxx
161# 创建一个简单的模型
2model = tf.keras.Sequential([
3 layers.Dense(10, activation='softmax', input_shape=(32,)),
4 layers.Dense(10, activation='softmax')
5])
6model.compile(optimizer='rmsprop',
7 loss='categorical_crossentropy',
8 metrics=['accuracy'])
9model.fit(data, labels, batch_size=32, epochs=5)
10
11
12# 将整个模型保存到HDF5文件
13model.save('my_model.h5')
14
15# 重新创建完全相同的模型,包括权重和优化器
16model = tf.keras.models.load_model('my_model.h5')
xxxxxxxxxx
21...
2Epoch 5/5 1000/1000 [==============================] - 0s 76us/sample - loss: 11.4913 - accuracy: 0.0990
在保存和序列化模型指南中,了解有关Keras模型的保存和序列化的更多信息。
Eager execution 是一种命令式编程环境,可立即评估操作。这不是Keras所必需的,但是由tf.keras
支持,对于检查程序和调试很有用。
所有 tf.keras
模型构建 API 都与 Eager Execution 兼容。虽然可以使用 Sequential
和函数式 API,但 Eager Execution 对模型子类化和构建自定义层特别有用。与通过组合现有层来创建模型的 API 不同,函数式 API 要求您编写前向传播代码。
请参阅 Eager Execution 指南,了解将 Keras 模型与自定义训练循环和 tf.GradientTape 搭配使用的示例 here.。
tf.keras
模型可以使用 tf.distribute.Strategy
在多个 GPU 上运行。此 API 在多个 GPU 上提供分布式训练,几乎不需要更改现有代码。
目前,tf.distribute.MirroredStrategy
是唯一受支持的分布策略。MirroredStrategy
通过在一台机器上使用规约在同步训练中进行图内复制。要使用distribute.Strategy
s,请在 Strategy
's .scope()
中嵌套优化器实例化和模型构造和编译,然后训练模型。
以下示例在单个计算机上的多个GPU之间分发tf.keras.Model
。
首先,在分布式策略范围内定义模型:
xxxxxxxxxx
121strategy = tf.distribute.MirroredStrategy()
2
3with strategy.scope():
4 model = tf.keras.Sequential()
5 model.add(layers.Dense(16, activation='relu', input_shape=(10,)))
6 model.add(layers.Dense(1, activation='sigmoid'))
7
8 optimizer = tf.keras.optimizers.SGD(0.2)
9
10 model.compile(loss='binary_crossentropy', optimizer=optimizer)
11
12model.summary()
xxxxxxxxxx
71Model: "sequential_5"
2_________________________________________________________________
3Layer (type) Output Shape Param # =================================================================
4dense_21 (Dense) (None, 16) 176 _________________________________________________________________
5dense_22 (Dense) (None, 1) 17 =================================================================
6Total params: 193 Trainable params: 193 Non-trainable params: 0
7_________________________________________________________________
接下来,像往常一样训练模型数据:
xxxxxxxxxx
71x = np.random.random((1024, 10))
2y = np.random.randint(2, size=(1024, 1))
3x = tf.cast(x, tf.float32)
4dataset = tf.data.Dataset.from_tensor_slices((x, y))
5dataset = dataset.shuffle(buffer_size=1024).batch(32)
6
7model.fit(dataset, epochs=1)
xxxxxxxxxx
1132/32 [==============================] - 3s 82ms/step - loss: 0.7005 <tensorflow.python.keras.callbacks.History at 0x7fdfa057fb00>
有关更多信息,请参阅TensorFlow中的分布式训练完整指南。
最新版本:https://www.mashangxue123.com/tensorflow/tf2-guide-keras-overview.html 英文版本:https://tensorflow.google.cn/beta/guide/keras/overview 翻译建议PR:https://github.com/mashangxue/tensorflow2-zh/edit/master/r2/guide/keras/overview.md