Tensorflow 可以计算出积分近似的梯度吗?
Can Tensorflow work out gradients for integral approximations?
我正在尝试使用哈密顿量 Monte Carlo(HMC,来自 Tensorflow Probability),但我的目标分布包含一个棘手的一维积分,我用梯形法则对其进行近似。我对 HMC 的理解是,它计算目标分布的梯度以构建更高效的过渡内核。我的问题是Tensorflow是否可以根据函数的参数计算出梯度,它们是否有意义?
例如,这是目标分布的对数概率,其中 'A' 是模型参数:
# integrate e^At * f[t] with respect to t between 0 and t, for all t
t = tf.linspace(0., 10., 100)
f = tf.ones(100)
delta = t[1]-t[0]
sum_term = tfm.multiply(tfm.exp(A*t), f)
integrals = 0.5*delta*tfm.cumsum(sum_term[:-1] + sum_term[1:], axis=0)
pred = integrals
sq_diff = tfm.square(observed_data - pred)
sq_diff = tf.reduce_sum(sq_diff, axis=0)
log_lik = -0.5*tfm.log(2*PI*variance) - 0.5*sq_diff/variance
return log_lik
这个函数在 A 方面的梯度有意义吗?
是的,您可以使用 tensorflow GradientTape 来计算梯度。我假设你有一个数学函数输出 log_lik
有很多输入,其中之一是 A
GradientTape 获取A的渐变
获取log_lik
相对于A
的梯度,可以使用tensorflowtf.GradientTape
中的
例如:
with tf.GradientTape(persistent=True) as g:
g.watch(A)
t = tf.linspace(0., 10., 100)
f = tf.ones(100)
delta = t[1]-t[0]
sum_term = tfm.multiply(tfm.exp(A*t), f)
integrals = 0.5*delta*tfm.cumsum(sum_term[:-1] + sum_term[1:], axis=0)
pred = integrals
sq_diff = tfm.square(observed_data - pred)
sq_diff = tf.reduce_sum(sq_diff, axis=0)
log_lik = -0.5*tfm.log(2*PI*variance) - 0.5*sq_diff/variance
z = log_lik
## then, you can get the gradients of log_lik with respect to A like this
dz_dA = g.gradient(z, A)
dz_dA
包含A
中变量的所有偏导数
我只是通过上面的代码向您展示了这个想法。为了使其工作,您需要通过 Tensor 运算进行计算。所以更改以修改您的函数以使用张量类型进行计算
另一个例子,但在张量运算中
x = tf.constant(3.0)
with tf.GradientTape() as g:
g.watch(x)
with tf.GradientTape() as gg:
gg.watch(x)
y = x * x
dy_dx = gg.gradient(y, x) # Will compute to 6.0
d2y_dx2 = g.gradient(dy_dx, x) # Will compute to 2.0
在这里你可以从文档中看到更多的例子来理解更多https://www.tensorflow.org/api_docs/python/tf/GradientTape
进一步讨论 "meaningfulness"
我先把python代码翻译成数学(我用的是https://www.codecogs.com/latex/eqneditor.php,希望能正常显示):
# integrate e^At * f[t] with respect to t between 0 and t, for all t
从上面看,这意味着你有一个功能。我称之为g(t, A)
那么你正在做一个定积分。我称之为 G(t,A)
从你的代码来看,t
不再是变量,它被设置为 10。所以,我们简化为一个只有一个变量的函数 h(A)
至此,函数h
内部有定积分。但是既然你是在逼近它,我们不应该把它当作一个真正的积分 (dt -> 0),它只是另一个 simple 数学链。这里没有神秘。
然后,最后的输出log_lik
,就是一些简单的数学运算加上一个新的输入变量observed_data
,我称之为y
。
那么计算 log_lik
的函数 z
是:
z
与 tensorflow 中其他正常的数学运算链没有什么不同。因此,dz_dA
是有意义的,因为 z
w.r.t A
的梯度给了你更新 A
的梯度,你可以最小化 z
我正在尝试使用哈密顿量 Monte Carlo(HMC,来自 Tensorflow Probability),但我的目标分布包含一个棘手的一维积分,我用梯形法则对其进行近似。我对 HMC 的理解是,它计算目标分布的梯度以构建更高效的过渡内核。我的问题是Tensorflow是否可以根据函数的参数计算出梯度,它们是否有意义?
例如,这是目标分布的对数概率,其中 'A' 是模型参数:
# integrate e^At * f[t] with respect to t between 0 and t, for all t
t = tf.linspace(0., 10., 100)
f = tf.ones(100)
delta = t[1]-t[0]
sum_term = tfm.multiply(tfm.exp(A*t), f)
integrals = 0.5*delta*tfm.cumsum(sum_term[:-1] + sum_term[1:], axis=0)
pred = integrals
sq_diff = tfm.square(observed_data - pred)
sq_diff = tf.reduce_sum(sq_diff, axis=0)
log_lik = -0.5*tfm.log(2*PI*variance) - 0.5*sq_diff/variance
return log_lik
这个函数在 A 方面的梯度有意义吗?
是的,您可以使用 tensorflow GradientTape 来计算梯度。我假设你有一个数学函数输出 log_lik
有很多输入,其中之一是 A
GradientTape 获取A的渐变
获取log_lik
相对于A
的梯度,可以使用tensorflowtf.GradientTape
中的
例如:
with tf.GradientTape(persistent=True) as g:
g.watch(A)
t = tf.linspace(0., 10., 100)
f = tf.ones(100)
delta = t[1]-t[0]
sum_term = tfm.multiply(tfm.exp(A*t), f)
integrals = 0.5*delta*tfm.cumsum(sum_term[:-1] + sum_term[1:], axis=0)
pred = integrals
sq_diff = tfm.square(observed_data - pred)
sq_diff = tf.reduce_sum(sq_diff, axis=0)
log_lik = -0.5*tfm.log(2*PI*variance) - 0.5*sq_diff/variance
z = log_lik
## then, you can get the gradients of log_lik with respect to A like this
dz_dA = g.gradient(z, A)
dz_dA
包含A
我只是通过上面的代码向您展示了这个想法。为了使其工作,您需要通过 Tensor 运算进行计算。所以更改以修改您的函数以使用张量类型进行计算
另一个例子,但在张量运算中
x = tf.constant(3.0)
with tf.GradientTape() as g:
g.watch(x)
with tf.GradientTape() as gg:
gg.watch(x)
y = x * x
dy_dx = gg.gradient(y, x) # Will compute to 6.0
d2y_dx2 = g.gradient(dy_dx, x) # Will compute to 2.0
在这里你可以从文档中看到更多的例子来理解更多https://www.tensorflow.org/api_docs/python/tf/GradientTape
进一步讨论 "meaningfulness"
我先把python代码翻译成数学(我用的是https://www.codecogs.com/latex/eqneditor.php,希望能正常显示):
# integrate e^At * f[t] with respect to t between 0 and t, for all t
从上面看,这意味着你有一个功能。我称之为g(t, A)
那么你正在做一个定积分。我称之为 G(t,A)
从你的代码来看,t
不再是变量,它被设置为 10。所以,我们简化为一个只有一个变量的函数 h(A)
至此,函数h
内部有定积分。但是既然你是在逼近它,我们不应该把它当作一个真正的积分 (dt -> 0),它只是另一个 simple 数学链。这里没有神秘。
然后,最后的输出log_lik
,就是一些简单的数学运算加上一个新的输入变量observed_data
,我称之为y
。
那么计算 log_lik
的函数 z
是:
z
与 tensorflow 中其他正常的数学运算链没有什么不同。因此,dz_dA
是有意义的,因为 z
w.r.t A
的梯度给了你更新 A
的梯度,你可以最小化 z