web-dev-qa-db-ja.com

熱心な実行を伴うTensorFlow 2.0で、特定のレイヤーに対するネットワーク出力の勾配を計算する方法は?

InceptionNetで作成したネットワークがあります。入力サンプルbxの場合、モデル出力w.r.tの勾配を計算します。非表示のレイヤー。私は次のコードを持っています:

_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)

_

しかし、これは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.
_

私のモデルは次のとおりです:

_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
_________________________________________________________________
_

どんな解決策もありがたいです。これらの勾配を計算する方法が他にある場合は、GradientTapeである必要はありません。

5
Vahid Mirjalili

すべてのレイヤーの出力に関する予測の勾配が必要な場合は、次のようにすることができます。

(@nessunoの構築 answer

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"),
    ]
)

# build a new model
output_layer = model.outputs
all_layers = [layer.output for layer in model.layers]
grad_model = tf.keras.model(inputs=model.inputs, outputs=all_layers)

inputs = tf.ones((1, 299, 299, 3))
with tf.GradientTape() as tape:
    output_of_all_layers = grad_model(inputs)
    preds = output_layer[-1]  # last layer is output layer
    # take gradients of last layer with respect to all layers in the model
    grads = tape.gradient(preds, output_of_all_layers)
    # note: grads[-1] should be all 1, since it it d(output)/d(output)
print(grads)
0
Ali Salehi