张量流中再次出现未聚集的梯度

时间:2019-03-20 10:23:16

标签: python tensorflow gradient gradient-descent

我的问题是关于tf.gradient(ys,xs),它总是为ys中的所有y返回sum(dy / dx)。总结是隐式的,似乎没有一种正式的方法可以获取每个y的渐变列表(例如,一批100个示例)。

我知道这里有些帖子也有类似的问题,但是似乎没有一个很好的答案。我的问题与在此讨论中提供的解决方案更相关:github issues。我想知道是否有人尝试过用户goodfeli提供的方法?这是我的尝试:

with tf.device('/GPU:4'):
    batch_size = 1000
    W = tf.Variable([[1.,2.],[3.,4.],[4.,8.],[3.,6.]])
    x = tf.placeholder(dtype = tf.float32, shape = [None,4])

    y = tf.tensordot(x,W,axes=1)
    loss = tf.reduce_prod(y)
    grad_old = tf.gradients(ys=loss,xs=W)

    ##Non Aggregate

    examples = tf.split(x,num_or_size_splits=batch_size)
    weight_copies = [tf.identity(W) for xs in examples]
    output = tf.stack([tf.tensordot(xs,ws,axes=1) for xs,ws in zip(examples,weight_copies)])
    batch_loss = tf.squeeze(tf.reduce_prod(output,axis=2))
    batch_grad = tf.gradients(ys=batch_loss,xs=weight_copies)
#Run session
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True,log_device_placement=False))
tf.global_variables_initializer().run(session=sess)

val = np.random.rand(batch_size,4)
fd = {x:val}
st0 = timeit.default_timer()
grad_b = np.array(sess.run(batch_grad,feed_dict=fd))
print("Batch: %f" %(timeit.default_timer()-st0))

st1 = timeit.default_timer()
grad_s = []
for s in val:
    val_x = [s]
    fds = {x:val_x}
    grad_s.append(sess.run(grad_old,feed_dict=fds)[0])
grad_s = np.array(grad_s)
print("Single: %f" %(timeit.default_timer()-st1))

但是,当我运行它时,批处理方法所花的时间比遍历每个示例所花的时间慢10倍左右。我觉得这很奇怪。当github线程似乎确认批处理方法更快时,是否有任何原因使它对我来说如此?我的设置是否过于简单,以至于开销扼杀了任何效率?任何帮助将不胜感激。

0 个答案:

没有答案