2017-02-10 1 views
7

Я использую TensorFlow для создания модели глубокого обучения. И новый для TensorFlow.Как обновить параметры модели с накопленными градиентами?

По какой-то причине моя модель имеет ограниченный размер партии, тогда этот ограниченный размер партии сделает модель высокой дисперсией.

Итак, я хочу использовать некоторый трюк, чтобы сделать размер партии более крупным. Моя идея состоит в том, чтобы сохранить градиенты каждой мини-партии, например 64 мини-пакета, а затем суммировать градиенты вместе, использовать средние градиенты этих 64 мини-партий учебных данных для обновления параметров модели.

Это означает, что для первых 63 мини-пакетов не обновляйте параметры, а после 64-разрядной партии обновите параметры модели только один раз.

Но поскольку TensorFlow основан на графике, кто-нибудь знает, как реализовать эту функцию?

Большое спасибо.

+0

Является [оптимизатором синхронизации реплик] (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/training/sync_replicas_optimizer.py), что вы ищете? –

+0

Кажется, я мог бы сохранить все средние градиенты, а затем вычислить среднее значение градиентов, а затем обновить параметры модели. – weixsong

+0

Оптимизатор синхронизации реплик, похоже, работает для нескольких параллельных тренировок с графическим процессором. Я посмотрю, посмотрим, смогу ли я использовать его. – weixsong

ответ

4

Я нашел решение здесь: https://github.com/tensorflow/tensorflow/issues/3994#event-766328647

opt = tf.train.AdamOptimizer() 
tvs = tf.trainable_variables() 
accum_vars = [tf.Variable(tf.zeros_like(tv.initialized_value()), trainable=False) for tv in tvs]           
zero_ops = [tv.assign(tf.zeros_like(tv)) for tv in accum_vars] 
gvs = opt.compute_gradients(rmse, tvs) 
accum_ops = [accum_vars[i].assign_add(gv[0]) for i, gv in enumerate(gvs)] 
train_step = opt.apply_gradients([(accum_vars[i], gv[1]) for i, gv in enumerate(gvs)]) 

В учебном цикле:

while True: 
    sess.run(zero_ops) 
    for i in xrange(n_minibatches): 
     sess.run(accum_ops, feed_dict=dict(X: Xs[i], y: ys[i])) 
    sess.run(train_step) 

Но этот код кажется не очень чистым и красиво, кто-нибудь знает, как оптимизировать этот код?

2

У меня была такая же проблема и только что разобрался.

Сначала получите символические градиенты, затем определите накопленные градиенты как tf.Variables. (Кажется, что tf.global_variables_initializer() должен быть запущен перед определением grads_accum. Я получил ошибки в противном случае, не знаю, почему.)

tvars = tf.trainable_variables() 
optimizer = tf.train.GradientDescentOptimizer(lr) 
grads = tf.gradients(cost, tvars) 

# initialize 
tf.local_variables_initializer().run() 
tf.global_variables_initializer().run() 

grads_accum = [tf.Variable(tf.zeros_like(v)) for v in grads] 
update_op = optimizer.apply_gradients(zip(grads_accum, tvars)) 

В обучении вы можете аккумулировать градиенты (сохраненные в gradients_accum) в каждой партии, а также обновление модели после работает на 64-й партии:

feed_dict = dict() 
for i, _grads in enumerate(gradients_accum): 
    feed_dict[grads_accum[i]] = _grads 
sess.run(fetches=[update_op], feed_dict=feed_dict) 

Вы можете обратиться к tensorflow/tensorflow/python/training/optimizer_test.py, например, использование, в частности, этой функции: testGradientsAsVariables().

Надеюсь, это поможет.

+0

Я не думаю, что этот код имеет отношение к вопросу. В какой момент суммируются грандиозные, т. Е. Накапливаются? Кроме того, в примере, на который вы ссылаетесь, градиенты не накапливаются; они вычисляются w.r.t. на два входа независимо. –

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

  • Нет связанных вопросов^_^