【问题标题】:Tensorflow gradients for every item of tensor每个张量项的张量流梯度
【发布时间】:2018-11-10 16:36:31
【问题描述】:

我有一个网络,它将Nx3 矩阵作为输入并生成一个 N 维向量。假设批量大小为 1 且 N=1024,因此输出的形状为 (1,1024)。我想计算输出的每个维度相对于输入的梯度。也就是说,dy/dx 对应每个 y。然而 tensorflow 的 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 的列表是否越来越大并占用更多内存。不幸的是,我无法对这段代码进行详细的内存分析。关于是什么导致迭代时间随着时间的推移而爆炸的任何想法?

(请注意,在代码中,我只是创建渐变操作,而不是实际评估它们。这部分稍后会出现,但由于上述极度减速,我的代码没有到达那里)

谢谢。

【问题讨论】:

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


    【解决方案1】:

    导致执行时间变长的是,您在 for 循环的每次迭代中都在图上定义了一个新操作。每次调用 tf.gradient 和 tf.reduce_mean 都会将一个新节点推送到图上。然后它需要重新编译才能运行。实际上应该为您工作的是使用带有 int32 占位符的tf.gather,它为您的渐变操作提供维度。所以是这样的:

    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])})
    

    【讨论】:

      猜你喜欢
      • 2016-08-20
      • 1970-01-01
      • 2023-03-27
      • 2016-09-12
      • 2020-12-10
      • 1970-01-01
      • 2018-07-30
      • 1970-01-01
      相关资源
      最近更新 更多