如何得到keras模型相对于其输入的梯度?

wvyml7n5  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(95)

我只是问了一个关于同一主题的问题,但对于自定义模型(How do I find the derivative of a custom model in Keras?),但很快意识到这是试图在我可以走路之前运行,所以这个问题被标记为这个问题的重复。
我尝试简化我的场景,现在有一个(非自定义)keras模型,由2个Dense层组成:

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 = ...

字符串
现在我想知道outputsinputs的导数,其中inputs = input_data

到目前为止,我已经尝试了:

This answer to a different question建议运行grads = K.gradients(model.output, model.input)。然而,如果我运行它,我会得到这个错误;
启用即时执行时不支持tf.gradients。请改用tf. gradient Tape。
我只能假设这与现在默认的急切执行有关。
另一种方法是在回答我关于定制keras模型的问题时,其中包括添加以下内容:

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


我不明白这种方法是如何加载数据的。它要求xvariable,但我的xtf.keras.Input对象。我也不明白with语句在做什么,某种魔术,但我不明白它。
这里有一个听起来非常相似的问题:Get Gradients with Keras Tensorflow 2.0尽管应用程序和场景完全不同,我很难将答案应用于这个场景。它确实导致我在代码中添加了以下内容:

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


这确实有效,但是现在怎么办?我运行model.predict(...),但是我如何得到我的梯度?答案说我应该运行t.gradient(outputs, x_tensor).numpy(),但是我为x_tensor输入 * 什么 *?我没有输入变量。我在运行predict之后尝试运行t.gradient(outputs, model.inputs),但是结果如下:
x1c 0d1x的数据

ubof19bj

ubof19bj1#

最后,我用这个问题的答案的一个变体: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)

字符串
这使我能够在没有冗余计算的情况下获得输出和梯度。

5anewei6

5anewei62#

对于那些使用接受答案的方法仍然得到None的人,你可以在这里检查原因:https://github.com/tensorflow/tensorflow/issues/30190#issuecomment-583237279。如果你仍然得到None,请检查你的模型是否包含“keras.Input”,否则你的输入将被转换并变得不可追踪。当你的输入变得不可追踪时,梯度也是None。
我遇到了这个问题,原来我忘了把keras.Input在我的模型:D

相关问题