TensorFlow 2.3 最新版本来了!本文将由官方为你介绍更新内容,一睹为快吧!
该版本致力于提供一个新的工具来帮助您简化数据的加载与预处理,并且无论在单机或是多台机器,都能解决输入流水线的瓶颈问题。
tf.data.service
现代加速器如 GPU、TPU 速度非常快。为了避免性能瓶颈,数据加载和预处理流水线必须足够快,才得以保证及时向加速器提供所需数据。例如,假设您的 GPU 可以每秒分类 200 个示例,但是您的数据输入流水线每秒只能从磁盘加载 100 个示例数据。在这种情况下,您的 GPU 将有一半时间处于空闲状态(等待数据)。况且这是假设您的输入流水线已经与 GPU 同时运行,如果没有,则 GPU 在 66% 的时间在等待数据。
在这种情况下,您可以使用tf.data.experimental.service/相关文档 通过数据加载和预处理将任务分布到与您的训练工作同时运行的集群中,以生成 200 个示例。tf.data service 具有调取器-工作节点体系结构,其中有一个调度器对应多个工作节点。我们提供了建立集群的相关文档,以及示例,向您展示如何使用 Google Kubernetes Engine 部署集群。
运行 tf.data.service 后,可以利用 distribute 代码转换将分布式数据集处理添加到现有的 tf.data 流水线中:
ds = your_dataset()
ds = dataset.apply(tf.data.experimental.service.distribute(processing_mode="parallel_epochs", service=service_address))
现在,当您迭代数据集时,将使用 tf.data service,而不是在本地计算机上进行。
分布式输入流水线是一项强大的功能,如果您是单机使用,tf.data 仍然对您有帮助。tf.data 包含了用于 提升输入流水线性能的工具 。请务必检查 cache 和 perfetch 转换,一行代码即可大幅提升流水线的处理速度。
tf.data snapshot
新添加的 tf.data.experimental.snapshot
API,可以将预处理流水线的输出长久储存到磁盘,进而在运行不同的训练任务时可重复利用预处理的数据。实际上,这有助于通过消耗磁盘存储空间以释放更多宝贵的 CPU 和加速器时间。
例如,假设您有一个预处理成本极高的数据集(比如您需要裁剪或旋转图像)。在构建了用于加载和预处理数据的输入线流水线之后:
dataset = create_input_pipeline()
您可以通过 snapshot 转换将结果保存到磁盘中:
dataset = dataset.apply(tf.data.experimental.snapshot("/snapshot_dir"))
Snapshot 将首次迭代的数据集存储在磁盘上。随后的迭代将从 snapshot_dir 读取,而不再重新计算数据集元素。
Snapshot 通过计算生成数据集的指纹,以便检测输入流水线是否发生变化,并自动重新计算过时的 snapshot。例如,如果您修改 Dataset.map 转换或将其他图像添加到源目录,则指纹将会变化,从而导致重新计算 snapshot。请注意,snapshot 无法对 现有 文件的更改进行检测。查看相关文档以了解更多信息。
TF Profiler 新功能
自 TensorFlow 2.2 引入 TF Profiler 之后,检查性能瓶颈变得更加容易。它可以帮助您锁定应用程序输入受限的情况,并尝试提供解决建议。您可以在这篇使用 TF Profiler 分析 tf.data 性能指南
中进一步熟悉它的工作流程。
在 TF 2.3 中,Profiler 有一些新功能和可用性改进。
在 TF 2.3 中,Keras 新增优化用户体验的实用程序:image_dataset_from_directory 和 text_dataset_from_directory
。您只需一个函数调用,便可从磁盘上的图像或文本文件目录创建 tf.data.Dataset。假如您的目录结构是这样:
flowers_photos/
├──daisy/
├──dandelion/
├──roses/
├──sunflowers/
└──tulips/
使用 image_dataset_from_directory 创建一个 tf.data.Dataset,从子目录和标签中生成多个批次的图像:
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
“datasets/cats_and_dogs”,
validation_split=0.2,
subset="training",
seed=0,
image_size=(img_height, img_width),
batch_size=32)
如果您要开始一个新项目,我们推荐使用 image_dataset_from_directory 替代旧版的 ImageDataGenerator。请注意,该程序无法执行数据增强(数据增强需由新的预处理层来完成,后文详述)。您可以在此处找到使用此实用程序加载图像的完整示例(以及如何使用 tf.data 从头开始编写类似的输入流水线)。
性能预测
创建 tf.data.Dataset 后(无论是从头开始创建还是使用 image_dataset_from_directory ),请记住对其优化配置以提高性能,以确保在训练模型时 I/O 不会成为瓶颈。您可以使用以下一行代码:
train_ds = train_ds.cache().prefetch(buffer_size=tf.data.experimental.AUTOTUNE)
这样便创建了一个将图像缓存在内存中的数据集(在第一个训练周期开始后从磁盘加载到内存),并同时执行 CPU 上的预处理任务与 GPU 上的训练任务。如果数据集过大无法读取内存中,则还可以使用 .cache ( filename ) 自动创建高效的磁盘缓存,其读取速度比许多小文件快。
请参阅 tf.data API 性能优化指南了解详情。
新的 Keras 预处理层
在 TF 2.3 中,Keras 还实验性地新添了预处理层 (Module: tf.keras.layers.experimental.preprocessing
) ,用以简化部署。您可将预处理逻辑打包为层添加至模型 内部,这样在导出模型时,它们就像其他层一样被保存下来。
学习使用这些新图层的最佳方法便是实践,您可参考从零开始文本分类,从零开始图像分类,以及 从零开始结构化数据分类 。更多教程示例请访问 keras.io。
请注意,所有层都可以包含在模型中,也可以通过映射转换应用于 tf.data 输入流水线。您可以在此处找到示例。
请记住,这些新的预处理层在 TF 2.3 中仍然是实验性功能。我们对这些新设计感到满意(并期望在 2.4 版本中将它们晋升为稳定的 API),但我们知道到我们很难在一次迭代中做到尽善尽美。非常欢迎您提供反馈。请在 GitHub 上提 issue ,让我们知道应如何更好地支持您的用例。
请查看 版本说明 以获取更多信息。
更多官方一手资讯,尽在 TensorFlow官方微信公众号( TensorFlow_official ),快扫码关注,将产品更新、课程教学、应用实践等精彩内容一网打尽吧!