2015-12-22 8 views
10

最近、私はTensorFlowを使用していましたが、フレームワークで利用できるすべての計算リソースを使用できないと述べました。 Convolutional Neural Networksチュートリアルでは、彼らはTensorFlowでの非同期計算

は、単純にモデルパラメータの非同期更新を採用していることに言及個々のモデルのレプリカは、モデルパラメータの古いコピーに訓練される可能性があるため、次善のトレーニングのパフォーマンスにつながります。逆に、完全同期の更新を使用すると、最も遅いモデルのレプリカほど遅くなります。

彼らはチュートリアルとwhitepaperの両方で言及していますが、ローカルマシンで非同期並列計算を行う方法は実際には見つかりませんでした。それも可能ですか?または、TensorFlowの配布予定バージョンの一部です。そうなら、どうですか?

+1

私はちょうど私がこの質問を理解するのに十分なほどスマートだったらいいと思う。運が良かった。 – GojiraDeMonstah

答えて

26

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() 

注:以下のようにコードがおおよそになります。

+0

これはとても簡単なので、本当に私の心には来なかった:)ありがとう。 –

+0

@VojtechLetal答えを受け入れてください – fabrizioM

+0

ここでマルチ処理ではなく、Pythonスレッドモジュールを使用した理由はありますか? – darshan