如何在tensorflow中复制GradientTape对象?(蒙特卡洛应用程序)

2024-05-14 08:43:08 发布

您现在位置:Python中文网/ 问答频道 /正文

在tensorflow中执行计算之前,我有一个昂贵的初始化操作

我的代码如下所示:

x = tf.Variable(2.0)
w = tf.Variable(5.0)

with tf.GradientTape() as tape:
  tape.watch(x)
  tape.watch(w)
  y = x ** 2
  z = w ** 3
  o = tf.math.log(y*z) # note that this step is the arbitrarily complex init code

# now i need to run a loop n times (here n is 10)
res = []
for i in range(10):
  with tape:
    z =tf.random.normal([1,10])
    f = tf.reduce_sum(x*z, axis=1)*o+w
  df = tape.gradient(f, {'x':x, 'w':w})
  res.append(df)

基本上,我正在尝试运行蒙特卡罗模拟,需要梯度,而不必在每个循环上运行初始化代码。如果n==1,此代码工作正常,但如果n>;则给出错误的答案=2.

我需要的是一种在开始蒙特卡罗循环之前复制磁带状态的方法。因此,与其说“用磁带”,不如说:

  with tf.GradientTape(tape) as tape2:
    ...
  df = tape2.gradient(f, {'x':x, 'w':w})

这可能吗?我怎样才能实现类似的目标

作为问题的第二部分,我注意到即使我在主循环中重新计算o的值,tensorflow也只在磁带不持久的情况下工作。如果是-我在循环几次之后耗尽了GPU上的内存。这并不理想,因为我还想定义其他依赖于x和w的函数,并记录它们的梯度

即,如果我这样做:

res = []
for i in range(10):
  with tf.GradientTape(persistent=True) as tape:
    z =tf.random.normal([1,10])

    # rerun init for every loop
    y = x ** 2
    t = w ** 3
    o = tf.math.log(y*t)

    f = tf.reduce_sum(x*z, axis=1)*o+w
    g = tf.reduce_sum(x*z+w, axis=1)*o

  df = tape.gradient(f, {'x':x, 'w':w})
  dg = tape.gradient(g, {'x':x, 'w':w})
  res.append([df,dg])

我不理解这种行为——在循环的每次迭代之后,磁带肯定会被丢弃(因此,它是否持久并不重要)

谢谢


Tags: 代码reducedffortftensorflowaswith

热门问题