2022 年 9 月 6 日 — TensorFlow 团队发布 TensorFlow 2.10 已发布!此版本亮点包括 Keras 中的易用功能,以帮助您开发 Transformer,确定性和无状态初始化器,优化器 API 更新,以及帮助您加载音频数据的工具。我们还通过 oneDNN 进行了性能改进,扩展了 Windows 上的 GPU 支持,等等。此版本还标志着 TensorFlow Decision Forests 1.0 的发布!继续阅读以了解更多信息。
TensorFlow 团队发布
TensorFlow 2.10 已发布!此版本亮点包括 Keras 中的易用功能,以帮助您开发 Transformer,确定性和无状态初始化器,优化器 API 更新,以及帮助您加载音频数据的工具。我们还通过 oneDNN 进行了性能改进,扩展了 Windows 上的 GPU 支持,等等。此版本还标志着 TensorFlow Decision Forests 1.0 的发布!继续阅读以了解更多信息。
从 TensorFlow 2.10 开始,Keras 注意力层的掩码处理,例如 tf.keras.layers.Attention,tf.keras.layers.AdditiveAttention 和 tf.keras.layers.MultiHeadAttention 已扩展和统一。特别是,我们添加了两个功能
因果注意力:所有三个层现在都支持一个 use_causal_mask 参数到 call (Attention 和 AdditiveAttention 过去使用 causal 参数到 __init__)。
隐式掩码:Keras Attention, AdditiveAttention,以及 MultiHeadAttention 层现在支持 隐式掩码 (在 tf.keras.layers.Embedding 中设置 mask_zero=True )。
结合起来,这简化了任何 Transformer 风格模型的实现,因为正确地获取掩码通常是一个棘手的部分。
一个基本的 Transformer 自注意力块现在可以写成
import tensorflow as tf
embedding = tf.keras.layers.Embedding(
input_dim=10,
output_dim=3,
mask_zero=True) # Infer a correct padding mask.
# Instantiate a Keras multi-head attention (MHA) layer,
# a layer normalization layer, and an `Add` layer object.
mha = tf.keras.layers.MultiHeadAttention(key_dim=4, num_heads=1)
layernorm = tf.keras.layers.LayerNormalization()
add = tf.keras.layers.Add()
# Test input.
x = tf.constant([[1, 2, 3, 4, 5, 0, 0, 0, 0],
[1, 2, 1, 0, 0, 0, 0, 0, 0]])
# The embedding layer sets the mask.
x = embedding(x)
# The MHA layer uses and propagates the mask.
a = mha(query=x, key=x, value=x, use_causal_mask=True)
x = add([x, a]) # The `Add` layer propagates the mask.
x = layernorm(x)
# The mask made it through all layers.
print(x._keras_mask)
以下是输出结果:
> tf.Tensor( > [[ True True True True True False False False False] > [ True True True False False False False False False]], shape=(2, > 9), dtype=bool) |
在之前的版本 TensorFlow 2.9 中,我们发布了 Keras 优化器 API 的新版本,在 tf.keras.optimizers.experimental 中,它将在 TensorFlow 2.11 中替换当前的 tf.keras.optimizers 命名空间。为了为即将到来的优化器命名空间正式切换到新 API 做准备,我们还在 TensorFlow 2.10 中将所有当前的 Keras 优化器导出到 tf.keras.optimizers.legacy 下。
大多数用户不会受到此更改的影响,但请查看 API 文档 以查看工作流中使用的任何 API 是否已更改。如果您决定继续使用旧优化器,请将优化器显式更改为相应的 tf.keras.optimizers.legacy.Optimizer。
您还可以在此 文章 中找到有关新 Keras 优化器的更多详细信息。
在 TensorFlow 2.10 中,我们使 Keras 初始化器( tf.keras.initializers API)无状态且确定性,构建在无状态 TF 随机操作之上。从 TensorFlow 2.10 开始,带种子和不带种子的 Keras 初始化器每次调用时都会生成相同的数值(对于给定的变量形状)。无状态初始化器使 Keras 能够支持新的功能,例如使用 DTensor 的多客户端模型训练。
init = tf.keras.initializers.RandomNormal() a = init((3, 2)) b = init((3, 2)) # a == b init_2 = tf.keras.initializers.RandomNormal(seed=1) c = init_2((3, 2)) d = init_2((3, 2)) # c == d # a != c init_3 = tf.keras.initializers.RandomNormal(seed=1) e = init_3((3, 2)) # e == c init_4 = tf.keras.initializers.RandomNormal() f = init_4((3, 2)) # f != a |
对于不带种子的初始化器 (seed=None),将在初始化器创建时创建一个随机种子并分配给它(不同的初始化器实例获得不同的种子)。不带种子的初始化器如果被重复使用(调用),将会发出警告。这是因为它每次都会生成相同的数值,这可能不是预期的行为。
在之前的版本 TensorFlow 2.9 中, tf.keras.callbacks.BackupAndRestore Keras 回调会在 epoch 边界备份模型和训练状态。在 TensorFlow 2.10 中,回调还可以在每 N 个训练步长备份模型。但是,请记住,当 BackupAndRestore 与 tf.distribute.MultiWorkerMirroredStrategy 一起使用时,分布式数据集迭代器状态将被重新初始化,并且在恢复模型时不会被恢复。有关更多信息和代码示例,请参阅 迁移容错机制 指南。
您现在可以使用一个新的实用程序,tf.keras.utils.audio_dataset_from_directory,轻松地从 .wav 文件目录生成音频分类数据集。 只需将您的音频文件按每个文件类别一个不同的目录进行排序,一行代码即可获得一个带标签的 tf.data.Dataset ,您可以将其传递给 Keras 模型。您可以在此处找到示例 示例。
einsum 函数是线性代数的瑞士军刀。它可以有效且明确地描述各种操作。 tf.keras.layers.EinsumDense 层将部分这种能力带入了 Keras。
像 einsum, einops.rearrange,以及 EinsumDense 层根据描述输入和输出轴的字符串“方程式”进行操作。对于 EinsumDense ,方程式列出了输入参数的轴、权重的轴以及输出的轴。一个基本的 Dense 层可以写成:
dense = keras.layers.Dense(units=10, activation='relu') dense = keras.layers.EinsumDense('...i, ij -> …j', output_shape=(10,), activation='relu') |
注意
例如,这里有 5 个 Dense 层,每层有 10 个单元
dense = keras.layers.EinsumDense('...i, nij -> …nj', output_shape=(5,10)) |
这里有一组 Dense 层,其中每一层都作用于不同的输入向量
dense = keras.layers.EinsumDense('...ni, nij -> …nj', output_shape=(5,10)) |
这里有一组 Dense 层,其中每一层都独立地作用于每个输入向量
dense = keras.layers.EinsumDense('...ni, mij -> …nmj', output_shape=(None, 5,10)) |
我们与 Arm、AWS 和 Linaro 合作,通过 oneDNN 将 Arm® 架构计算库 (ACL) 整合到 TensorFlow 中,以加速 aarch64 CPU 上的性能。从 TensorFlow 2.10 开始,您可以在运行 TensorFlow 程序之前设置环境变量 TF_ENABLE_ONEDNN_OPTS=1 来尝试这些实验性优化。
由于不同的计算和浮点舍入方法,可能会出现略微不同的数值结果。如果这给您造成问题,请在运行程序之前通过设置 TF_ENABLE_ONEDNN_OPTS=0 来关闭优化。
要验证优化是否开启,请在您的程序日志中查找以“oneDNN 自定义操作已开启”开头的消息。欢迎您在 GitHub 和 TensorFlow 论坛 上提供反馈。
TensorFlow 现在可以通过 TensorFlow-DirectML 插件 利用更广泛的 Windows 上的 GPU。要在来自 AMD、英特尔、NVIDIA 和 Qualcomm 等供应商的 DirectX 12 支持的 GPU 上启用模型训练,请在原生 Windows 或 WSL2 上与标准 TensorFlow CPU 软件包一起安装此插件。该 预览包 目前支持有限数量的基本机器学习模型,目标是将来增加模型覆盖范围。您可以在 TensorFlow-DirectML GitHub 存储库 中查看开源代码并留下反馈。
Tensorflow 2.10 引入了一个方便的新实验性 API tf.data.experimental.from_list ,它创建了一个 tf.data.Dataset ,包含给定的元素列表。返回的数据集将逐个产生列表中的项目。当元素是标量时,该功能与 tf.data.Dataset.from_tensor_slices 相同,但当元素具有结构时则不同。
请考虑以下示例
dataset = tf.data.experimental.from_list([(1, 'a'), (2, 'b'), (3, 'c')]) list(dataset.as_numpy_iterator()) [(1, 'a'), (2, 'b'), (3, 'c')] |
相反,要使用 `from_tensor_slices` 获得相同的输出,需要重新组织数据
dataset = tf.data.Dataset.from_tensor_slices(([1, 2, 3], ['a', 'b', 'c'])) list(dataset.as_numpy_iterator()) [(1, 'a'), (2, 'b'), (3, 'c')] |
与 from_tensor_slices 方法不同,from_list 支持非矩形输入(使用 from_tensor_slices 实现相同的效果需要使用 不规则张量)。
如果您使用相同训练数据并发运行多个训练器,将数据缓存在一个 tf.data 服务集群中并与训练器共享该集群可以节省资源。例如,如果您使用 Vizier 调整超参数,Vizier 作业可以并发运行并共享一个 tf.data 服务集群。
要启用此功能,每个训练器都需要生成一个唯一的训练器 ID,并将该训练器 ID 传递给 tf.data.experimental.service.distribute。作业消耗数据后,数据将保留在缓存中,并由具有不同 trainer_ids 的作业重复使用。具有相同 trainer_id 的请求不会重复使用数据。例如
dataset = expensive_computation() dataset = dataset.apply(tf.data.experimental.service.distribute( processing_mode=tf.data.experimental.service.ShardingPolicy.OFF, service=FLAGS.tf_data_service_address, job_name="job", cross_trainer_cache=data_service_ops.CrossTrainerCache( trainer_id=trainer_id()))) |
tf.data 服务使用滑动窗口缓存来存储共享数据。当一个训练器消耗数据时,该数据将保留在缓存中。当其他训练器需要数据时,它们可以从缓存中获取数据,而不是重复进行昂贵的计算。缓存的大小有限,因此有些工作者可能无法读取完整的数据集。为了确保所有训练器都获得足够的训练数据,我们要求输入数据集是无限的。例如,可以通过重复数据集并在训练实例上执行随机增强来实现这一点。
随着 Tensorflow 2.10 的发布,Tensorflow 决策森林 (TF-DF) 达到 1.0 版本。我们希望通过这一里程碑更广泛地传达 TensorFlow 决策森林已经成为一个更稳定和更成熟的库。我们改进了我们的 文档 并建立了更全面的测试,以确保 TF-DF 准备好用于专业环境。
TF-DF 的新版本还首次展示了 Javascript 和 Go API,用于推断 TF-DF 模型。虽然这些 API 仍处于测试阶段,但我们正在积极寻求对它们的反馈。TF-DF 1.0 提高了性能 斜切分。斜切分允许决策树通过同时对多个特征进行条件判断来表达更复杂的模式——在 developers.google.com 上了解有关我们决策森林课程的更多信息。基准测试和现实世界观察表明,斜切分在大多数数据集上优于经典的轴对齐切分。最后,新版本包含了我们最新的错误修复。
查看 发行说明 以获取更多信息。要保持最新状态,您可以阅读 TensorFlow 博客、关注 twitter.com/tensorflow,或订阅 youtube.com/tensorflow。如果您构建了一些想分享的内容,请将其提交到 goo.gle/TFCS 上的社区亮点。对于反馈,请在 GitHub 上提交问题或发布到 TensorFlow 论坛。谢谢!