Pregunta

Estoy calculando y optimización de algunas variables que se utilizan en un proceso externo, pero recibo el error "sin gradiente".

Una versión muy simplificada (no probada) del código, pero puede obtener la idea:

def external_process (myvar):
    subprocess.call("process.sh", myvar)
    with open('result.json', 'r') as f:
        result = json.load(data, 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])[0] )

optimizer = tf.train.AdamOptimizer(0.05)
train_step = optimizer.minimize(loss)
sess.run(train_step)

Vi esta discusión pero no la entiendo completamente: https://github.com/tensorflow/tensorflow/issues/1095

¡Gracias!

¿Fue útil?

Solución 2

La respuesta correcta es: "Un proceso externo no es diferenciable (a menos que conozca cada detalle, lo que es imposible en este caso), por lo que este problema debe enfrentarse como un problema de aprendizaje de refuerzo"

Otros consejos

Aquí https://www.tensorflow.org/versions/r0.9/api_docs/python/framework.html (búsqueda gradient_override_map) es un ejemplo en gradient_override_map:

@tf.RegisterGradient("CustomSquare")
def _custom_square_grad(op, grad):
  # ...

with tf.Graph().as_default() as g:
  c = tf.constant(5.0)
  s_1 = tf.square(c)  # Uses the default gradient for tf.square.
  with g.gradient_override_map({"Square": "CustomSquare"}):
    s_2 = tf.square(s_2)  # Uses _custom_square_grad to compute the
                          # gradient of s_2.

Entonces, una posible solución podría ser:

@tf.RegisterGradient("ExternalGradient")
def _custom_external_grad(unused_op, grad):
    # I don't know yet how to compute a gradient
    # From Tensorflow documentation:
    return grad, tf.neg(grad)

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

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

g = tf.get_default_graph()
with g.gradient_override_map({"PyFunc": "ExternalGradient"}):
    external_data =  tf.py_func(external_process, [myvar], [tf.float32])[0]

loss =  tf.reduce_sum(external_data)

optimizer = tf.train.AdamOptimizer(0.05)
train_step = optimizer.minimize(loss)
sess.run(train_step)
Licenciado bajo: CC-BY-SA con atribución
scroll top