我试图按照Keras GradCam教程实现GradCam。
我在下面做了一个简化版本。不管我做什么,我的梯度都是None
。
import tensorflow as tffrom tensorflow import keras as Kimport numpy as npinputs = tf.keras.Input(shape=(224, 224, 12))x = K.applications.MobileNetV2(input_shape=(224, 224, 12), include_top=False, weights=None)(inputs)x = K.layers.GlobalAveragePooling2D()(x)x = K.layers.Dropout(0.25)(x)x = K.layers.Dense(16, activation='relu')(x)x = K.layers.Dropout(0.25)(x)x = K.layers.Dense(1, activation='sigmoid')(x)model = tf.keras.Model(inputs, x)img_array = np.random.rand(1, 224, 224, 12).astype(np.float32)grad_model = tf.keras.models.Model( [model.inputs], [model.layers[0].output, model.output])image = np.random.rand(1, 224, 224, 12).astype(np.float32)with tf.GradientTape() as tape: (convOutputs, predictions) = grad_model(image) loss = predictions[:, tf.argmax(predictions[0])]grads = tape.gradient(loss, convOutputs)print(grads)
None
回答:
得到None
值的原因是你正在计算相对于input
层的梯度。以下是上述情况的一种简单解决方案:
inputs = tf.keras.Input(shape=(224, 224, 12))x = K.applications.MobileNetV2(input_tensor=inputs, include_top=False, weights=None)x = K.layers.GlobalAveragePooling2D()(x.output)x = K.layers.Dropout(0.25)(x)x = K.layers.Dense(16, activation='relu')(x)x = K.layers.Dropout(0.25)(x)x = K.layers.Dense(1, activation='sigmoid')(x)model = tf.keras.Model(inputs, x)img_array = np.random.rand(1, 224, 224, 12).astype(np.float32)grad_model = tf.keras.models.Model( [model.inputs], [model.layers[1].output, model.output])model.layers[0].output, model.layers[1].output(<KerasTensor: shape=(None, 224, 224, 12) dtype=float32 (created by layer 'input_63')>, <KerasTensor: shape=(None, 112, 112, 32) dtype=float32 (created by layer 'Conv1')>)
在这里,我们使用layer[1]
。现在可以获取相对于此的输入梯度。
image = np.random.rand(1, 224, 224, 12).astype(np.float32) with tf.GradientTape() as tape: (convOutputs, predictions) = grad_model(tf.cast(image, tf.float32)) loss = predictions[:, tf.argmax(predictions[0])]grads = tape.gradient(loss, convOutputs)print(grads) tf.Tensor([[[[ 0.0000000e+00 -1.4619777e-16 -5.2771450e-17 ... -0.0000000e+00 0.0000000e+00 0.0000000e+00] [-7.5641491e-17 0.0000000e+00 -0.0000000e+00 ... -0.0000000e+00 -1.1224229e-16 0.0000000e+00] [-5.8784695e-17 1.0889748e-18 1.9431665e-16 ... 0.0000000e+00 0.0000000e+00 0.0000000e+00] ...