Tensorflow 出列在 Cloud ML 上非常慢

Tensorflow dequeue is very slow on Cloud ML

我正在尝试 运行 云端 CNN(Google Cloud ML),因为我的笔记本电脑没有 GPU 卡。

所以我将我的数据上传到 Google 云存储。包含 1500 个条目的 .csv 文件,如下所示:

    | label  |  img_path  |
    | label_1| /img_1.jpg |
    | label_2| /img_2.jpg |

以及相应的 1500 张 jpg。

我的 input_fn 看起来是这样的:

def input_fn(filename,
         batch_size,
         num_epochs=None,
         skip_header_lines=1,
         shuffle=False):
filename_queue = tf.train.string_input_producer(filename, num_epochs=num_epochs)
reader = tf.TextLineReader(skip_header_lines=skip_header_lines)
_, row = reader.read(filename_queue)
row = parse_csv(row)
pt = row.pop(-1)
pth = filename.rpartition('/')[0] + pt
img = tf.image.decode_jpeg(tf.read_file(tf.squeeze(pth)), 1)
img = tf.to_float(img) / 255.
img = tf.reshape(img, [IMG_SIZE, IMG_SIZE, 1])
row = tf.concat(row, 0)
if shuffle:
    return tf.train.shuffle_batch(
        [img, row],
        batch_size,
        capacity=2000,
        min_after_dequeue=2 * batch_size + 1,
        num_threads=multiprocessing.cpu_count(),
    )
else:
    return tf.train.batch([img, row],
                          batch_size,
                          allow_smaller_final_batch=True,
                          num_threads=multiprocessing.cpu_count())

这是完整的图表(确实是非常简单的 CNN):

运行 批量大小为 200 的训练,然后我笔记本电脑上的大部分计算时间(在我的笔记本电脑上,数据存储在本地)都花在了梯度节点上,这就是我想要的预计。批处理节点的计算时间约为 12 毫秒。

当我运行它在云端时(scale-tier是BASIC),批处理节点需要20多秒。根据张量板,瓶颈似乎来自 QueueDequeueUpToV2 子节点:

有人知道为什么会这样吗?我很确定我在这里弄错了,所以我很乐意学习。

几点说明: - 在 batch/shuffle_batch 与不同的 min_after_dequeue 之间切换不受影响。 - 使用BASIC_GPU时,批处理节点也在CPU上,根据我的阅读,这是正常的,大约需要13s。 - 在队列启动后添加一个time.sleep以确保不饥饿也没有效果。 -计算时间在 batch_size 中确实是线性的,因此 batch_size 为 50 时,计算时间比 batch_size 为 200 时小 4 倍。

感谢阅读,如果有人需要,我们很乐意提供更多详细信息。

最好的, 阿尔

更新:

-Cloud ML 实例和 Buckets 不在同一个区域,使它们在同一个区域提高了 4 倍的结果。

-创建 .tfrecords 文件使批处理花费 70 毫秒,这似乎是可以接受的。我就是以这个blogpost为起点来学习的,推荐

我希望这会帮助其他人创建一个快速的数据输入管道!

尝试将您的图像转换为 tfrecord 格式并直接从图形中读取它们。你这样做的方式,没有缓存的可能性,如果你的图像很小,你就没有利用云存储的高持续读取。将所有 jpg 图像保存到 tfrecord 文件或少量文件中会有所帮助。

此外,请确保您的存储桶是具有 GPU 的区域中的单个区域存储桶,并且您要提交到该区域中的 cloudml。

我以前遇到过类似的问题。我通过将 tf.train.batch() 更改为 tf.train.batch_join() 来解决它。在我的实验中,使用 64 个批量大小和 4 个 GPU,使用 tf.train.batch() 花费了 22 分钟,而使用 tf.train.batch_join() 只花费了 2 分钟。

在 Tensorflow 文档中:

如果您需要更多的并行性或在文件之间混洗示例,请使用 tf.train.shuffle_batch_join

的多个 reader 实例

https://www.tensorflow.org/programmers_guide/reading_data