How do I get the gradient of a keras model with respect to its inputs?

我的未来我决定 提交于 2020-01-22 03:09:18

问题


I just asked a question on the same topic but for custom models (How do I find the derivative of a custom model in Keras?) but realised quickly that this was trying to run before I could walk so that question has been marked as a duplicate of this one.

I've tried to simplify my scenario and now have a (not custom) keras model consisting of 2 Dense layers:

inputs = tf.keras.Input((cols,), name='input')

layer_1 = tf.keras.layers.Dense(
        10,
        name='layer_1',
        input_dim=cols,
        use_bias=True,
        kernel_initializer=tf.constant_initializer(0.5),
        bias_initializer=tf.constant_initializer(0.1))(inputs)

outputs = tf.keras.layers.Dense(
        1,
        name='alpha',
        use_bias=True,
        kernel_initializer=tf.constant_initializer(0.1),
        bias_initializer=tf.constant_initializer(0))(layer_1)

model = tf.keras.Model(inputs=inputs, outputs=outputs)

prediction = model.predict(input_data)
# gradients = ...

Now I would like to know the derivative of outputs with respect to inputs for inputs = input_data.

What I've tried so far:

This answer to a different question suggests running grads = K.gradients(model.output, model.input). However, if I run that I get this error;

tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.

I can only assume this is something to do with eager execution now being the default.

Another approach was in the answer to my question on custom keras models, which involved adding this:

with tf.GradientTape() as tape:
    x = tf.Variable(np.random.normal(size=(10, rows, cols)), dtype=tf.float32)
    out = model(x)

What I don't understand about this approach is how I'm supposed to load the data. It requires x to be a variable, but my x is a tf.keras.Input object. I also don't understand what that with statement is doing, some kind of magic but I don't understand it.

There's a very similar-sounding question to this one here: Get Gradients with Keras Tensorflow 2.0 although the application and scenario are sufficiently different for me to have difficulty applying the answer to this scenario. It did lead me to add the following to my code:

with tf.GradientTape() as t:
    t.watch(outputs)

That does work, but now what? I run model.predict(...), but then how do I get my gradients? The answer says I should run t.gradient(outputs, x_tensor).numpy(), but what do I put in for x_tensor? I don't have an input variable. I tried running t.gradient(outputs, model.inputs) after running predict, but that resulted in this:


回答1:


I ended up getting this to work with a variant of the answer to this question: Get Gradients with Keras Tensorflow 2.0

x_tensor = tf.convert_to_tensor(input_data, dtype=tf.float32)
with tf.GradientTape() as t:
    t.watch(x_tensor)
    output = model(x_tensor)

result = output
gradients = t.gradient(output, x_tensor)

This allows me to obtain both the output and the gradient without redundant computation.



来源:https://stackoverflow.com/questions/59590766/how-do-i-get-the-gradient-of-a-keras-model-with-respect-to-its-inputs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!