当前位置: 首页 > 面试题库 >

TensorFlow中的异步计算

海宁
2023-03-14
问题内容

最近,我一直在玩 TensorFlow,
并提到该框架无法使用我所有可用的计算资源。在卷积神经网络教程中,他们提到

天真地采用模型参数的异步更新会导致次优的训练性能,因为单个模型副本可能会在模型参数的陈旧副本上进行训练。相反,采用完全同步更新将与最慢的模型副本一样慢。

尽管他们在教程和白皮书中都提到了这一点,但我并没有真正找到在本地计算机上进行异步并行计算的方法。可能吗
还是它是TensorFlow发行版本的一部分。如果是,那怎么办?


问题答案:

TensorFlow的开源版本支持异步梯度下降,甚至无需修改图形。最简单的方法是 并行 执行多个 并发步骤

loss = ...

# Any of the optimizer classes can be used here.
train_op = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

sess = tf.Session()
sess.run(tf.initialize_all_variables())

def train_function():
  # TODO: Better termination condition, e.g. using a `max_steps` counter.
  while True:
    sess.run(train_op)

# Create multiple threads to run `train_function()` in parallel
train_threads = []
for _ in range(NUM_CONCURRENT_STEPS):
  train_threads.append(threading.Thread(target=train_function))

# Start the threads, and block on their completion.
for t in train_threads:
  t.start()
for t in train_threads:
  t.join()

本示例设置对的NUM_CONCURRENT_STEPS调用sess.run(train_op)。由于这些线程之间没有协调,因此它们异步进行。

(目前)实现 同步
并行训练实际上更具挑战性,因为这需要额外的协调以确保所有副本都读取相同版本的参数,并确保所有副本同时可见。用于CIFAR-10训练的多GPU示例通过在训练图中使用共享参数制作“塔”的多个副本,并在应用更新之前显式平均塔上的梯度来执行同步更新。

注意 :此答案中的代码将所有计算都放在同一设备上,如果您的计算机中有多个GPU,这将不是最佳选择。如果要使用所有GPU,请遵循多GPU
CIFAR-10模型的示例,并创建多个“塔”,并将其操作固定在每个GPU上。该代码大致如下:

train_ops = []

for i in range(NUM_GPUS):
  with tf.device("/gpu:%d" % i):
    # Define a tower on GPU `i`.
    loss = ...

    train_ops.append(tf.train.GradientDescentOptimizer(0.01).minimize(loss))

def train_function(train_op):
  # TODO: Better termination condition, e.g. using a `max_steps` counter.
  while True:
    sess.run(train_op)


# Create multiple threads to run `train_function()` in parallel
train_threads = []
for train_op in train_ops:
  train_threads.append(threading.Thread(target=train_function, args=(train_op,))


# Start the threads, and block on their completion.
for t in train_threads:
  t.start()
for t in train_threads:
  t.join()

请注意,您可能会发现使用“可变范围”方便了塔之间的变量共享。



 类似资料:
  • MXNet使用异步计算来提升计算性能。理解它的工作原理既有助于开发更高效的程序,又有助于在内存资源有限的情况下主动降低计算性能从而减小内存开销。我们先导入本节中实验需要的包或模块。 from mxnet import autograd, gluon, nd from mxnet.gluon import loss as gloss, nn import os import subproces

  • 我正面临着一个问题,即设计能够执行网络I/O的方法(用于可重用库)。我读过这个问题 API设计中C#5Await/Async模式 以及其他与我的问题更接近的问题。 所以,问题是,如果我想同时提供异步和非异步方法,我必须如何设计这些? 例如,要公开方法的非异步版本,我需要执行如下操作 我觉得这不是个好设计。我想要一个关于如何定义私有方法的建议(例如),这些私有方法可以包装在公共方法中以提供两个版本。

  • 问题内容: 我有一个对象,该对象带有一种方法,希望以类似以下方式向库客户端(尤其是脚本客户端)公开: 但是我可以使用的原始“东西”是一组事件驱动的类: 在其中,ImplementingThing接受输入,执行一些不可思议的工作,例如将任务排队入队列,然后稍后在发生结果时,在可能与调用ImplementingThing.doSomethingAsync()相同的线程上调用该线程。 有没有一种方法可以

  • 我需要有一个长时间运行的websocket客户端,它接收来自websocket服务器的推送消息,并且我需要监视客户端的连接状态:如果连接中断,我需要发现。 我的方法是定期记录一个常量字符串,如果没有检测到日志消息,就触发警报。 我的想法是:1)有一个websocket客户机来响应不定期传入的消息。2)同时有一个循环,当websocket客户机抛出一个ConnectionClosed exeptio

  • 我希望我的请求触发一些长时间运行的操作,这些操作应该在后台执行。我编写了以下实现,应该在后台处理我的操作,但实际上我的请求是同步执行的: 在日志中,我看到以下内容: 我看到我的在另一个线程中执行,但出于某种原因,我的原始请求等待sleep完成 更新1:

  • 如果我在main中这样做,它将创建一个新线程,并将向其提交一个任务以进行异步计算。 如果您看到FutureTask文档,它还会说: 可取消的异步计算。此类提供了Future的基本实现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法。 那么,FutureTask是如何进行异步计算的呢?它是否在内部创建线程,并提交我们在实例化FutureTask时给它的任务,比如: 否则它不可能是异步计算