我正在尝试在python中编写一些自定义TensorFlow函数(使用tf.py_func
),我想在python中计算结果和渐变。我正在使用gradient_override_map
技巧(例如来自https://gist.github.com/harpone/3453185b41d8d985356cbe5e57d67342和How to make a custom activation function with only Python in Tensorflow?)。
然而,当向前方向的函数获得一个numpy数组作为输入时,渐变的函数得到Tensor
s。这是一个问题,取决于调用函数的时间,因为可能没有默认会话,和/或可能没有包含所有必需值的feed_dict(例如,在tf.train优化器中)。 / p>
如何在前向和后向函数中获取(并返回)numpy数组的py_func?
示例代码:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
def sin_func(x):
return np.sin(x)
def sin_grad_func(op, grad):
x = op.inputs[0].eval()
grad = grad.eval() # <--- this is what I'd like to avoid
output_grad = np.cos(x) * grad
return tf.convert_to_tensor(output_grad)
def py_func(func, inp, Tout, stateful=True, name=None, grad_func=None):
grad_name = 'PyFuncGrad_' + str(np.random.randint(0, 1E+8))
tf.RegisterGradient(grad_name)(grad_func)
g = tf.get_default_graph()
with g.gradient_override_map({"PyFunc": grad_name}):
return tf.py_func(func, inp, Tout, stateful=stateful, name=name)
with tf.Session() as sess:
np_x = np.linspace(0, np.pi, num=1000, dtype=np.float32)
x = tf.constant(np_x)
y = py_func(sin_func,
[x],
[tf.float32],
name='np_sin',
grad_func=sin_grad_func)
y = y[0]
gr = tf.gradients(y, [x])
tf.global_variables_initializer().run()
plt.plot(y.eval())
plt.plot(gr[0].eval())
答案 0 :(得分:1)
如果您想在渐变函数中包含任意Python代码,最简单的解决方案是在tf.py_func()
内创建另一个sin_grad_func()
:
def sin_grad_func_impl(x, grad):
return np.cos(x) * grad
def sin_grad_func(op, grad):
return tf.py_func(sin_grad_func_impl, [x, grad], grad.dtype)