如何获得 keras 模型相对于其输入的梯度?
How do I get the gradient of a keras model with respect to its inputs?
我刚刚问了一个关于同一主题但针对自定义模型的问题 (),但很快意识到这是在 运行 我可以走路之前尝试,所以该问题已被标记为这个的副本。
我试图简化我的场景,现在有一个(非自定义)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 = ...
现在我想知道 outputs
关于 inputs
的导数对于 inputs
= input_data
.
到目前为止我已经尝试过:
建议运行宁grads = K.gradients(model.output, model.input)
。但是,如果我 运行 我得到这个错误;
tf.gradients is not supported when eager execution is enabled. Use
tf.GradientTape instead.
我只能假设这与现在默认的急切执行有关。
另一种方法是在回答我关于自定义 keras 模型的问题时添加以下内容:
with tf.GradientTape() as tape:
x = tf.Variable(np.random.normal(size=(10, rows, cols)), dtype=tf.float32)
out = model(x)
我不明白这种方法是我应该如何加载数据。它要求 x
是一个 variable
,但我的 x
是一个 tf.keras.Input
对象。我也不明白 with
语句在做什么,有点神奇,但我不明白。
这里有一个听起来非常相似的问题: 尽管应用程序和场景差异很大,我很难将答案应用到这个场景中。它确实引导我将以下内容添加到我的代码中:
with tf.GradientTape() as t:
t.watch(outputs)
那确实有效,但现在呢?我 运行 model.predict(...)
,但是我如何获得渐变?答案说我应该 运行 t.gradient(outputs, x_tensor).numpy()
,但是 我应该为 x_tensor
输入什么 ?我没有输入变量。我在 运行ning predict
之后尝试了 运行ning t.gradient(outputs, model.inputs)
,但结果是:
我最终使用这个问题的变体答案来解决这个问题:
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)
这使我无需冗余计算即可获得输出和梯度。
我刚刚问了一个关于同一主题但针对自定义模型的问题 (
我试图简化我的场景,现在有一个(非自定义)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 = ...
现在我想知道 outputs
关于 inputs
的导数对于 inputs
= input_data
.
到目前为止我已经尝试过:
grads = K.gradients(model.output, model.input)
。但是,如果我 运行 我得到这个错误;
tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.
我只能假设这与现在默认的急切执行有关。
另一种方法是在回答我关于自定义 keras 模型的问题时添加以下内容:
with tf.GradientTape() as tape:
x = tf.Variable(np.random.normal(size=(10, rows, cols)), dtype=tf.float32)
out = model(x)
我不明白这种方法是我应该如何加载数据。它要求 x
是一个 variable
,但我的 x
是一个 tf.keras.Input
对象。我也不明白 with
语句在做什么,有点神奇,但我不明白。
这里有一个听起来非常相似的问题:
with tf.GradientTape() as t:
t.watch(outputs)
那确实有效,但现在呢?我 运行 model.predict(...)
,但是我如何获得渐变?答案说我应该 运行 t.gradient(outputs, x_tensor).numpy()
,但是 我应该为 x_tensor
输入什么 ?我没有输入变量。我在 运行ning predict
之后尝试了 运行ning t.gradient(outputs, model.inputs)
,但结果是:
我最终使用这个问题的变体答案来解决这个问题:
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)
这使我无需冗余计算即可获得输出和梯度。