【发布时间】:2020-09-30 17:04:01
【问题描述】:
我正在努力解决以下问题。我正在使用 from_generator 方法创建一个 tf.data.Dataset。我在 CPU 上执行这些操作,因为我不想让我的 GPU 内存过载。
数据集由元组组成,其中包含一个固定长度的 tf.bool 一维掩码 (tf.Tensor) 和一个可变大小的 tf.float 二维矩阵 (tf.Tensor)。损失函数使用以下装饰器进行装饰,因此我不会认为可变大小是问题。
@tf.function(experimental_relax_shapes=True)
理想情况下,数据集保存在 CPU 上,然后预取到 GPU 上。
def gen():
for i, j in zip(mask_list, wmat_list):
yield i, j
dataset = tf.data.Dataset.from_generator(gen, output_types=(tf.bool, tf.float32))
目前主要的训练循环依赖 tf.identity 将数据移动到 gpu,效率低下。如下面 Tensorboard 的屏幕截图所示。大约 70% 的时间用于加载数据并将其移动到 GPU。
for b, (mask, wmat) in enumerate(dataset):
with tf.GradientTape() as tape:
mask = tf.identity(mask)
wmat = tf.identity(wmat)
mean_error, loss = self.model.loss(mask, wmat)
epoch_loss += loss.numpy()
epoch_mean_error += mean_error.numpy()
我已经尝试过“prefetch_to_device”功能。但是,它没有将数据移动到 GPU 上。通过打印验证,例如训练循环中的 mask.device。
gpu_transform = tf.data.experimental.prefetch_to_device('/gpu')
dataset.apply(gpu_transform)
对我来说,它类似于这个错误:https://github.com/tensorflow/tensorflow/issues/30929。但是,它被标记为已解决并且已经超过一年了。
使用官方 Docker 镜像运行 TF 2.3。
【问题讨论】: