# Tensorflow - How to set gradient of an external process (py_func)?

I'm computing and optimization of some Variables that are used on an external process, but I get the error "No Gradient".

A heavily simplified (not tested) version of the code, but you can get the idea:

def external_process (myvar):
subprocess.call("process.sh", myvar)
with open('result.json', 'r') as f:
return np.array(result["result"])

myvar = tf.Variable(1.0, dtype = 'float32', trainable = True)

loss = tf.reduce_sum( tf.py_func(external_process, [myvar], [tf.float32]) )

train_step = optimizer.minimize(loss)
sess.run(train_step)


I saw this discussion but I don't fully understand it: https://github.com/tensorflow/tensorflow/issues/1095

Thanks!

Here https://www.tensorflow.org/versions/r0.9/api_docs/python/framework.html (search gradient_override_map) is an example on gradient_override_map:

@tf.RegisterGradient("CustomSquare")
# ...

with tf.Graph().as_default() as g:
c = tf.constant(5.0)
s_1 = tf.square(c)  # Uses the default gradient for tf.square.
s_2 = tf.square(s_2)  # Uses _custom_square_grad to compute the


So, a possible solution could be:

@tf.RegisterGradient("ExternalGradient")
# I don't know yet how to compute a gradient
# From Tensorflow documentation:

def external_process (myvar):
subprocess.call("process.sh", myvar)
with open('result.json', 'r') as f:
return np.array(result["result"])

myvar = tf.Variable(1.0, dtype = 'float32', trainable = True)

g = tf.get_default_graph()

• Note that an alternative approach would be to wrap it using function.Defun instead of using gradient_override_map. – Albert Jun 8 '17 at 8:03