每个张量的Tensorflow梯度

时间:2018-11-10 16:36:31

标签: python python-3.x tensorflow deep-learning

我有一个网络,它使用Nx3矩阵作为输入并产生N维向量。假设批量大小为1且N = 1024,所以输出的形状为(1,1024)。我想针对输入针对输出的每个维度计算渐变。也就是说,每dy/dx就有y。但是,张量流的tf.gradients计算d sum(y)/dx的总和。我知道没有一种简单的方法可以计算每个输出维的梯度,因此我最终决定运行tf.gradients 1024次,因为我只需要在项目中执行一次,就不必再执行一次。

所以我这样做:

start = datetime.datetime.now()
output_code_split = tf.split(output_code,1024)
#output shape = (1024,)
grad_ops = []
for i in range(1024):
    gr = tf.gradients(output_code_split[i],input)
    #output shape = (1024,1,16,1024,3) , where 16= batch size

    gr = tf.reduce_mean(gr,[0,1,2,3])
    #output shape = (1024,)

    grad_ops.append(gr)
    present = datetime.datetime.now()
    print(i,(present-start).seconds,flush=True)
    #prints time taken to finish previous computation.
    start = datetime.datetime.now()

当代码开始运行时,两次迭代之间的时间 为4秒,因此我认为它将运行大约4096秒。但是,随着迭代次数的增加,后续运行所花费的时间也不断增加。间隔是在代码启动时为4秒,在大约500次迭代后最终达到30秒,这太大了。

保存渐变操作grad_ops的列表是否更大并且占用更多内存。不幸的是,我无法对此代码进行详细的内存分析。有关导致迭代时间随时间推移而耗费时间的任何想法?

(请注意,在代码中,我仅创建渐变操作而不是实际评估它们。稍后介绍该部分,但由于上述极端缓慢的原因,我的代码未到达该位置)

谢谢。

1 个答案:

答案 0 :(得分:0)

浪费执行时间的是,您在for循环的每次迭代中都在图上定义了一个新操作。对tf.gradienttf.reduce_mean的每次调用都会在图上推送一个新节点。然后需要重新编译才能运行。实际应该为您使用的是将tf.gather与一个int32占位符一起使用,该占位符为渐变操作提供尺寸。像这样:

idx_placeholder = tf.placeholder(tf.int32, shape=(None,))
grad_operation = tf.gradients(tf.gather(output_code_split, idx_placeholder))
for i in range(1024):
      sess.run(grad_operation, {idx_placeholder: np.array([i])})