Python 梯度如何通过tf.py_func
这是tensorflow中更快的R-CNN实现。Python 梯度如何通过tf.py_func,python,machine-learning,tensorflow,neural-network,Python,Machine Learning,Tensorflow,Neural Network,这是tensorflow中更快的R-CNN实现。 这是由python编写的 我很好奇梯度是否可以通过tf.py_func 权重和偏差不断变化 因此,我认为梯度反馈成功 然后我做一个小测试 import tensorflow as tf import numpy as np def addone(x): # print type(x) return x + 1 def pyfunc_test(): # create data x_data = tf.placeh
这是由python编写的 我很好奇梯度是否可以通过
tf.py_func
权重和偏差不断变化
因此,我认为梯度反馈成功 然后我做一个小测试
import tensorflow as tf
import numpy as np
def addone(x):
# print type(x)
return x + 1
def pyfunc_test():
# create data
x_data = tf.placeholder(dtype=tf.float32, shape=[None])
y_data = tf.placeholder(dtype=tf.float32, shape=[None])
w = tf.Variable(tf.constant([0.5]))
b = tf.Variable(tf.zeros([1]))
y1 = tf.mul(w, x_data, name='y1')
y2 = tf.py_func(addone, [y1], tf.float32)
y = tf.add(y2, b)
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for step in xrange(201):
ran = np.random.rand(115).astype(np.float32)
ans = ran * 1.5 + 3
dic = {x_data: ran, y_data: ans}
tt, yy, yy1= sess.run([train, y1, y2], feed_dict=dic)
if step % 20 == 0:
print 'step {}'.format(step)
print '{}, {}'.format(w.eval(), b.eval())
test = sess.run(y, feed_dict={x_data:[1]})
print 'test = {}'.format(test)
if __name__ == '__main__':
pyfunc_test()
变量b
保持更改,但w
在初始化后保持值不变
sess.run(tf.gradients(loss,b),feed\u dict=dic)
get valuesess.run(tf.gradients(loss,w),feed_dict=dic)
get{TypeError}Fetch参数无无效类型
我知道有些问题建议使用
tf.RegisterGradient
和渐变覆盖图
但我在更快的rcnn回购(帖子顶部的链接)中找不到这些内容
我是做错了什么还是遗漏了什么,以至于
w
冻结了py\u函数的梯度None
(只需检查ops.get\u Gradient\u函数(y2.op)
)。@harpone展示了如何对py_func使用渐变覆盖贴图
下面是您的示例,已修改为使用该配方
import numpy as np
import tensorflow as tf
def addone(x):
# print(type(x)
return x + 1
def addone_grad(op, grad):
x = op.inputs[0]
return x
from tensorflow.python.framework import ops
import numpy as np
# Define custom py_func which takes also a grad op as argument:
def py_func(func, inp, Tout, stateful=True, name=None, grad=None):
# Need to generate a unique name to avoid duplicates:
rnd_name = 'PyFuncGrad' + str(np.random.randint(0, 1E+8))
tf.RegisterGradient(rnd_name)(grad) # see _MySquareGrad for grad example
g = tf.get_default_graph()
with g.gradient_override_map({"PyFunc": rnd_name}):
return tf.py_func(func, inp, Tout, stateful=stateful, name=name)
def pyfunc_test():
# create data
x_data = tf.placeholder(dtype=tf.float32, shape=[None])
y_data = tf.placeholder(dtype=tf.float32, shape=[None])
w = tf.Variable(tf.constant([0.5]))
b = tf.Variable(tf.zeros([1]))
y1 = tf.mul(w, x_data, name='y1')
y2 = py_func(addone, [y1], [tf.float32], grad=addone_grad)[0]
y = tf.add(y2, b)
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.01)
train = optimizer.minimize(loss)
print("Pyfunc grad", ops.get_gradient_function(y2.op))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for step in range(10):
# ran = np.random.rand(115).astype(np.float32)
ran = np.ones((115)).astype(np.float32)
ans = ran * 1.5 + 3
dic = {x_data: ran, y_data: ans}
tt, yy, yy1= sess.run([train, y1, y2], feed_dict=dic)
if step % 1 == 0:
print('step {}'.format(step))
print('{}, {}'.format(w.eval(), b.eval()))
test = sess.run(y, feed_dict={x_data:[1]})
print('test = {}'.format(test))
if __name__ == '__main__':
pyfunc_test()
谢谢你的回答,我知道harpone的要点,但是我在更快的rcnn回购中找不到tf.RegisterGradient
,所以我想知道是否可能只通过py_func而不使用tf.RegisterGradient
,或者跳过层tf.RegisterGradient
是核心TensorFlow的一部分,请尝试帮助(tf.RegisterGradient)
在Python shellok中,我发现更快的R-CNN repo中的tf.py_func
的梯度无法传递,但一些损失是由tf.py_func
之前的值计算出来的。因此,即使tf.py_func
的梯度为零,在tf.py_func
之前的权重也可以更新。为什么在addone_grad
中返回x
而不是返回grad
?您可以返回grad,这只是一个非标准梯度的例子