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である必要はありません。
すべてのレイヤーの出力に関する予測の勾配が必要な場合は、次のようにすることができます。
(@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)