在具有急切执行的 TensorFlow 2.0 中,如何计算特定层的网络输出的梯度?

Vah*_*ili 9 python gradient tensorflow tf.keras tensorflow2.0

我有一个用 InceptionNet 制作的网络,对于输入样本bx,我想计算隐藏层的模型输出的梯度。我有以下代码:

bx = tf.reshape(x_batch[0, :, :, :], (1, 299, 299, 3))


with tf.GradientTape() as gtape:
    #gtape.watch(x)
    preds = model(bx)
    print(preds.shape, end='  ')

    class_idx = np.argmax(preds[0])
    print(class_idx, end='   ')

    class_output = model.output[:, class_idx]
    print(class_output, end='   ')

    last_conv_layer = model.get_layer('inception_v3').get_layer('mixed10')
    #gtape.watch(last_conv_layer)
    print(last_conv_layer)


grads = gtape.gradient(class_output, last_conv_layer.output)#[0]
print(grads)

Run Code Online (Sandbox Code Playgroud)

但是,这会给None. 我也试过gtape.watch(bx)了,但它仍然给出None.

在尝试 GradientTape 之前,我尝试使用tf.keras.backend.gradient但出现如下错误:

RuntimeError: tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.
Run Code Online (Sandbox Code Playgroud)

我的模型如下:

model.summary()

Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
inception_v3 (Model)         (None, 1000)              23851784  
_________________________________________________________________
dense_5 (Dense)              (None, 2)                 2002      
=================================================================
Total params: 23,853,786
Trainable params: 23,819,354
Non-trainable params: 34,432
_________________________________________________________________
Run Code Online (Sandbox Code Playgroud)

任何解决方案表示赞赏。如果有任何其他方法来计算这些梯度,它不一定是 GradientTape。

nes*_*uno 1

您可以使用磁带来计算输出节点的梯度,以及一组可观察对象。默认情况下,可训练变量可通过磁带观看,并且您可以通过按名称获取并访问属性来访问特定层的可训练变量trainable_variables

例如,在下面的代码中,我计算预测的梯度,仅相对于第一个 FC 层(名称“fc1”)的变量,考虑任何其他变量为常量。

import tensorflow as tf

model = tf.keras.models.Sequential(
    [
        tf.keras.layers.Dense(10, input_shape=(3,), name="fc1", activation="relu"),
        tf.keras.layers.Dense(3, input_shape=(3,), name="fc2"),
    ]
)

inputs = tf.ones((1, 299, 299, 3))

with tf.GradientTape() as tape:
    preds = model(inputs)

grads = tape.gradient(preds, model.get_layer("fc1").trainable_variables)
print(grads)
Run Code Online (Sandbox Code Playgroud)