2015-12-22 3 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() 

Этот пример устанавливает NUM_CONCURRENT_STEPS звонков в sess.run(train_op). Поскольку между этими потоками нет координации, они работают асинхронно.

Это на самом деле более сложный для достижения синхронного параллельного обучения (в настоящее время), так как это требует дополнительного согласования для обеспечения того, чтобы все реплики прочитать ту же версию параметров, и что все их обновлений становятся видимыми одновременно , multi-GPU example for CIFAR-10 training выполняет синхронные обновления, создавая несколько копий «башни» на графике обучения с общими параметрами и явно усредняя градиенты через башни перед применением обновления.


N.B. Код в этом ответе помещает все вычисления на одно и то же устройство, которое не будет оптимальным, если на вашем компьютере установлено несколько графических процессоров. Если вы хотите использовать все свои графические процессоры, следуйте примеру multi-GPU CIFAR-10 model и создайте несколько «башен» с их операциями, прикрепленными к каждому графическому процессору. Код будет выглядеть примерно следующим образом:

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

Обратите внимание, что вы можете найти его удобно использовать "variable scope" для облегчения переменного обмена между башнями.

+0

Это так просто, что это действительно не пришло мне на ум :) Большое спасибо. –

+0

@VojtechLetal, пожалуйста, принимайте ответ – fabrizioM

+0

. Есть ли причина, по которой вы использовали pingon threading module вместо многопроцессорной обработки? – darshan

Смежные вопросы