- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在尝试了解有关使用 tf.data 构建高效预处理管道的更多信息。根据this tutorial缓存数据时对性能的影响应该是不可忽略的。
我将数据管道简化为一个非常简单的示例来验证这种效果。
import os
import tensorflow as tf
class ExperimentalDS:
def __init__(self, hr_img_path, cache, repeat, shuffle_buffer_size=4096):
self.hr_img_path = hr_img_path
self.ids = os.listdir(self.hr_img_path)
self.train_list = self.ids
train_list_ds = tf.data.Dataset.list_files([f"{hr_img_path}/{fname}" for fname in self.train_list])
train_hr_ds = train_list_ds.map(self.load_img)
train_hr_ds = train_hr_ds.shuffle(shuffle_buffer_size)
self.train_ds = train_hr_ds
# should probably call shuffle again after caching
if cache: self.train_ds.cache()
self.train_ds = train_hr_ds.repeat(repeat)
def get_train_ds(self, batch_size=8):
return self.train_ds.batch(batch_size).prefetch(tf.data.experimental.AUTOTUNE)
def load_img(self, fpath):
img = tf.io.read_file(fpath)
img = tf.image.decode_png(img)
img = tf.image.convert_image_dtype(img, tf.float32)
return img
管道基本上只是从文件夹中读取文件名,从这些文件名加载图像,随机排列图像,然后缓存它们或不缓存它们,具体取决于提供的参数。
为了评估性能,我主要复制了前面提到的教程中的基准测试函数。
def benchmark_dataset(ds, num_steps):
start = time.perf_counter()
it = iter(ds)
for i in range(num_steps):
batch = next(it)
if i % 100 == 0:
print(".", end="")
print()
end = time.perf_counter()
duration = end - start
return duration
if __name__ == "__main__":
num_steps = 1000
batch_size = 8
durations_no_cache = []
durations_cached = []
for i in range(num_steps):
ds = ExperimentalDS("./test_data/benchmark/16", cache=False, repeat=-1)
ds_train = ds.get_train_ds(batch_size=batch_size)
durations_no_cache.append(benchmark_dataset(ds_train, num_steps))
for i in range(num_steps):
ds = ExperimentalDS("./test_data/benchmark/16", cache=True, repeat=-1)
ds_train = ds.get_train_ds(batch_size=batch_size)
durations_cached.append(benchmark_dataset(ds_train, num_steps))
os.makedirs(SAVE_PATH, exist_ok=True)
durations_no_cache = np.array(durations_no_cache)
avg_duration_no_cache = np.average(durations_no_cache)
durations_cached = np.array(durations_cached)
avg_durations_cached = np.average(durations_cached)
with open(f"{SAVE_PATH}/stats", "a+") as f:
f.write("no cache:\n")
f.write(f"{num_steps} batches: {avg_duration_no_cache}s (avg)\n")
f.write(f"{batch_size*num_steps/avg_duration_no_cache:.5f} Images/s\n\n")
f.write("cached:\n")
f.write(f"{num_steps} batches: {avg_durations_cached}s (avg)\n")
f.write(f"{batch_size*num_steps/avg_durations_cached:.5f} Images/s")
我正在加载一个非常简单的图像数据集,其中包含 16 个图像,每个图像的尺寸为 128x128(因此它应该很容易装入内存)。我无限期地重复此数据集,并在使用缓存和不使用缓存的情况下迭代 1000 个批处理(批处理大小为 8),记录运行时间,然后对 1000 次运行的结果进行平均。由于这些运行次数相当多,因此我认为应该不会有太大差异。如果重要的话,基准测试是在 GPU 上运行的。
结果令我非常惊讶。没有缓存的基准测试实际上稍微快一些:
no cache:
1000 batches: 2.434403038507444s (avg)
3286.22659 Images/scached:
1000 batches: 2.439824645938235s (avg)
3278.92417 Images/s
我知道还有一些其他方法可以提高性能,例如并行和矢量化映射,但它在比较缓存与不缓存方面不应该产生任何影响。
有人可以帮我解决这个问题吗?我在这里缺少什么?
编辑:在评论中,@Szymon Maszke 建议我应该对多个时期的迭代进行基准测试,并将数据实际馈送到网络。所以我这样做了,但是缓存和未缓存的数据集的性能几乎相同。真的不知道为什么。
edit2:修复了@AAudibert指出的错误后,它现在按预期工作。事实上,老实说,它的工作效果比预期的要好:
no cache:
1000 batches: 2.624478972374927s (avg)
3048.22408 Images/scached:
1000 batches: 0.17946020061383025s (avg)
44578.12915 Images/s
最佳答案
此语句不执行任何操作:
if cache: self.train_ds.cache()
应该是:
if cache: train_hr_ds = train_hr_ds.cache()
与其他数据集转换一样,缓存
返回新数据集,而不是修改现有数据集。
关于python - tf.data.Dataset - 为什么当我缓存示例时数据管道的性能没有提高?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60172564/
如果我用 dataset.batch(n).prefetch(m), 将预提取m个批次或m个 sample ? 最佳答案 Dataset.prefetch(m) 转换预取其直接输入的m元素。在这种情况
根据 TensorFlow documentation 、tf.contrib.data.Dataset 类的 prefetch 和 map 方法,都有一个名为 buffer_size 的参数. 对于
我正在使用 Flink 0.10.1 的 DataSet API 编写应用程序。我可以在 Flink 中使用单个运算符获取多个收集器吗? 我想做的是如下所示: val lines = env.read
为了使用 Google Colabs TPU,我需要一个 tf.dataset.Dataset .那么如何在这样的数据集上使用数据增强? 更具体地说,到目前为止我的代码是: def get_datas
我有一个包含 2 个相关数据表(主数据表和详细信息)的数据集。我想将与我的过滤器匹配的数据(例如主数据列 A =“XXX”)复制到另一个数据集。 现在我发现这个过程需要很长时间(1k 条记录大约需要一
我正在使用 .pvd文件同时加载多个文件到 Paraviw。对于具有单个数据集的时间序列,该文件看起来像这样: 我想指定要与 a.*.vtu 一起加载的其他文件(
我听说 Google 主办(或将举办)一场网络分类竞赛,他们提供了一个大型(170k+ 文档)网站数据集,这些网站被分为多个类别(体育、计算机、科学等),我尝试环顾四周在他们的 2009 年到 201
谁能给我解释一下 DataSet.Copy() vs Dataset.Clone()也让我知道一些我们可以使用这些的场景 最佳答案 Clone 将创建一个新的空数据集,其架构(表和列)与旧数据集相同。
dataset = dataset.batch(50) dataset = dataset.prefetch(buffer_size=1) 是预取 1 个批次还是 1 个元素? 根据 tensorfl
在 Delphi 中,与 Dataset.Next 相比,使用 Dataset.Prior 是否会降低性能? 背景: 我有一个在数据集中搜索特定记录的例程。我从数据集中的最后一条记录开始,然后使用 D
我正在使用 Spark(2.0) 开发 Spark SQL,并使用 Java API 读取 CSV。 CSV 文件中有一个双引号、逗号分隔的列。例如:“Express Air,Delivery Tru
为什么要使用DataSet.BeginInit 和DataSet.EndInit? 我已经经历了official msdn documentation ,它说 Begins the initializ
我正在尝试向新的数据集 X 添加一个位于不同数据集 Y 中的数据表。如果我直接添加它,我会得到以下错误: DataTable already belongs to another DataSet. 我
我有一个表示为形状为 (num_features, num_examples) 的 NumPy 矩阵的数据集,我希望将其转换为 TensorFlow 类型 tf.Dataset。 我正在努力理解这两种
这是 question 的转发在 ai.stackexchange 中询问。由于该论坛没有太多吸引力,我想我可以在这里尝试一下机会。 我有一个特定对象的不同尺寸的图像数据集。该物体的一些图像也处于不同
我有两个数据集: main_ds = tf.data.Dataset.from_tensor_slices(list(range(1000, 1100))) backgroud_ds = tf.dat
拥有Dataset单列 json 字符串: +--------------------+ | value| +--------------------+ |{"Contex
我正在尝试解决 Azure 数据工厂中的以下场景: 我在 Azure Blob 存储中有大量文件夹。每个文件夹包含不同数量的 parquet 格式的文件。文件夹名称包含生成该文件夹中包含的数据的日期,
我正在尝试解决 Azure 数据工厂中的以下场景: 我在 Azure Blob 存储中有大量文件夹。每个文件夹包含不同数量的 parquet 格式的文件。文件夹名称包含生成该文件夹中包含的数据的日期,
我有一个顺序数据集,我可以从中创建窗口来训练 RNN。在某些情况下,我想扔掉某些 window 。但是,当我使用 dataset.window 和 dataset.filter 时,管道内部会出现一些
我是一名优秀的程序员,十分优秀!