如何获得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
是变量
,但myx
是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)