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()
この例ではsess.run(train_op)
にNUM_CONCURRENT_STEPS
の呼び出しを設定します。これらのスレッド間の調整はないため、非同期で処理を進めます。
これだ、これはすべてのレプリカは、パラメータの同じバージョンを読んでいること、およびそのすべての更新が同時に見えるようになることを確実にするために、追加の調整を必要とするため、(現時点では)同期並列訓練を達成するために、実際より挑戦。 multi-GPU example for CIFAR-10 trainingは、共有パラメータを使用して訓練グラフの「タワー」の複数のコピーを作成し、更新を適用する前に塔全体のグラジエントを明示的に平均化することで同期更新を実行します。
N.B.この回答のコードは、すべての計算を同じデバイスに置きます。これは、マシンに複数のGPUがある場合は最適ではありません。すべてのGPUを使用する場合は、multi-GPU CIFAR-10 modelの例に従って、各GPUに動作が固定された複数の「タワー」を作成します。あなたはそれが便利鉄塔間の変数の共有を容易にするために、"variable scope"を使用することを見つけるかもしれない
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()
注:以下のようにコードがおおよそになります。
私はちょうど私がこの質問を理解するのに十分なほどスマートだったらいいと思う。運が良かった。 – GojiraDeMonstah