如何在 tensorflow 中制作 GradientTape 对象的副本? 蒙特卡洛应用

问题描述

在 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,'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,'w':w})
  dg = tape.gradient(g,'w':w})
  res.append([df,dg])

我不理解这种行为 - 在每次循环迭代后磁带肯定会被丢弃(因此它是否持久都无关紧要)?

谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...