【发布时间】:2018-02-09 17:55:03
【问题描述】:
这可能与Tensorflow: How to get gradients per instance in a batch? 重复。反正我也问了,因为一直没有满意的答案,而且这里的目标有点不一样。
我有一个非常大的网络,可以安装在我的 GPU 上,但我可以提供的最大批量大小是 32。任何比这更大的都会导致 GPU 内存不足。我想使用更大的批次以获得更准确的梯度近似值。
具体而言,假设我想通过依次输入 3 批 32 来计算大量 96 的梯度。我知道的最好方法是使用Optimizer.compute_gradients() 和Optimizer.apply_gradients()。这是一个如何工作的小例子
import tensorflow as tf
import numpy as np
learn_rate = 0.1
W_init = np.array([ [1,2,3], [4,5,6], [7,8,9] ], dtype=np.float32)
x_init = np.array([ [11,12,13], [14,15,16], [17,18,19] ], dtype=np.float32)
X = tf.placeholder(dtype=np.float32, name="x")
W = tf.Variable(W_init, dtype=np.float32, name="w")
y = tf.matmul(X, W, name="y")
loss = tf.reduce_mean(y, name="loss")
opt = tf.train.GradientDescentOptimizer(learn_rate)
grad_vars_op = opt.compute_gradients(loss)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# Compute the gradients for each batch
grads_vars1 = sess.run(grad_vars_op, feed_dict = {X: x_init[None,0]})
grads_vars2 = sess.run(grad_vars_op, feed_dict = {X: x_init[None,1]})
grads_vars3 = sess.run(grad_vars_op, feed_dict = {X: x_init[None,2]})
# Separate the gradients from the variables
grads1 = [ grad for grad, var in grads_vars1 ]
grads2 = [ grad for grad, var in grads_vars2 ]
grads3 = [ grad for grad, var in grads_vars3 ]
varl = [ var for grad, var in grads_vars1 ]
# Average the gradients
grads = [ (g1 + g2 + g3)/3 for g1, g2, g3 in zip(grads1, grads2, grads3)]
sess.run(opt.apply_gradients(zip(grads,varl)))
print("Weights after 1 gradient")
print(sess.run(W))
现在这一切都非常丑陋和低效,因为前向传播是在 GPU 上运行的,而平均梯度发生在 CPU 上,然后再次在 GPU 上应用它们。
此外,此代码会引发异常,因为grads 是np.arrays 的列表,要使其正常工作,必须为每个渐变创建一个tf.placeholder。
我确定应该有更好、更有效的方法来做到这一点?有什么建议吗?
【问题讨论】:
标签: machine-learning tensorflow backpropagation gradient-descent tensorflow-gpu