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

如何获得keras模型相对于其输入的梯度?,keras,tensorflow2.0,Keras,Tensorflow2.0,我只是问了一个关于同一主题的问题,但针对自定义模型(),但很快意识到这是在我能够走路之前尝试运行的,因此该问题已标记为此问题的重复 我试图简化我的场景,现在有了一个(不是定制的)keras模型,由两个密集的层组成: inputs = tf.keras.Input((cols,), name='input') layer_1 = tf.keras.layers.Dense( 10, name='layer_1', input_dim=cols,

我只是问了一个关于同一主题的问题,但针对自定义模型(),但很快意识到这是在我能够走路之前尝试运行的,因此该问题已标记为此问题的重复

我试图简化我的场景,现在有了一个(不是定制的)
keras
模型,由两个
密集的
层组成:

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 = ...
现在我想知道
输入的
输出
相对于
输入的导数

到目前为止我所尝试的:

建议运行
grads=K.gradients(model.output,model.input)
。然而,如果我运行,我会得到这个错误

启用“急切执行”时不支持tf.gradients。使用 用梯度胶带代替

我只能假设这与现在默认的急切执行有关

另一种方法是在回答我关于定制keras模型的问题时,其中包括添加以下内容:

with tf.GradientTape() as tape:
    x = tf.Variable(np.random.normal(size=(10, rows, cols)), dtype=tf.float32)
    out = model(x)
关于这种方法,我不理解的是我应该如何加载数据。它要求
x
变量
,但my
x
tf.keras.Input
对象。我也不明白
with
语句在做什么,某种魔力,但我不明白

这里有一个听起来非常类似的问题:尽管应用程序和场景有很大的不同,我很难将答案应用到这个场景中。这确实让我在代码中添加了以下内容:

with tf.GradientTape() as t:
    t.watch(outputs)
这确实管用,但现在怎么办?我运行
model.predict(…)
,但是我如何得到我的梯度呢?答案是我应该运行
t.gradient(outputs,x_tensor).numpy()
,但是我应该为
x_tensor
输入什么呢?我没有输入变量。在运行
predict
之后,我尝试运行
t.gradient(输出、模型、输入)
,但结果是:


我最终得到了这个问题的一个不同答案:


这使我能够在不进行冗余计算的情况下获得输出和梯度。

这与您之前的问题有什么不同?在Keras中,所有模型都是自定义的。@MatiasValdenegro这是不同的,因为我不再创建从tf.Keras.model继承的自定义模型类。有关更多信息,请参见此:这不会改变梯度的计算方式,因此解决方案是相同的,因此是相同的问题。@MatiasValdenegro请随意回答我的任何一个问题。我仍然找不到答案@YOLO权重不是梯度。是否真的需要将输入numpy数组转换为张量?如果没有它,它可能会工作。我认为你不需要在那里观看。我一直在使用
GradientTape
在急切模式下训练很多模型。我从未使用过
watch
@MatiasValdenegro,我不确定,但可能是因为他们试图获得数据的“梯度”,所以在这种情况下,数据可能需要是张量?@MatiasValdenegro
.numpy()
不是必需的。我会删除它。@DanielMöller我试着删除
watch
,但是
t.gradient
如果我这样做,就会返回
NoneType
。我认为这与张量是否“可训练”有关。我正在使用
scipy
进行训练,因此
keras
可能无法识别可训练的重量。
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)