Jan*_*lly 4 computer-vision heatmap deep-learning keras tensorflow
我正在尝试使用 keras 为 MNIST 构建一个基本的“普通梯度”显着性热图(基于梯度的特征归因)。我知道有像这样的库可以计算显着性热图,但我想从头开始构建它,因为普通梯度方法在概念上似乎很容易实现。我使用函数模型定义在 Keras 中训练了以下数字分类器:
input = layers.Input(shape=(28,28,1), name='input')
conv2d_1 = layers.Conv2D(32, kernel_size=(3, 3), activation='relu')(input)
maxpooling2d_1 = layers.MaxPooling2D(pool_size=(2, 2), name='maxpooling2d_1')(conv2d_1)
conv2d_2 = layers.Conv2D(64, kernel_size=(3, 3), activation='relu')(maxpooling2d_1)
maxpooling2d_2 = layers.MaxPooling2D(pool_size=(2, 2))(conv2d_2)
flatten = layers.Flatten(name='flatten')(maxpooling2d_2)
dropout = layers.Dropout(0.5, name='dropout')(flatten)
dense = layers.Dense(num_classes, activation='softmax', name='dense')(dropout)
model = keras.models.Model(inputs=input, outputs=dense)
Run Code Online (Sandbox Code Playgroud)
现在,我想计算单个 MNIST 图像的显着图。由于最后一层有一个softmax激活并且分母是一个归一化项(以便输出节点加起来为1),我相信我需要要么采用softmax前的输出,要么改变训练模型的激活线性计算显着图。我会做后者。
model.layers[-1].activation = tf.keras.activations.linear # swap activation to linear
input = loaded_model.layers[0].input
output = loaded_model.layers[-1].output
input_image = x_test[0] # shape is (28, 28, 1)
pred = np.argmax(loaded_model.predict(np.expand_dims(input_image, axis=0))) # predicted class
Run Code Online (Sandbox Code Playgroud)
但是,我不知道除此之外还能做什么。我知道我可以使用以下内容K.gradients(output, input)
来计算梯度。话虽这么说,我相信我应该计算预测类相对于输入图像的梯度,而不是计算整个输出的梯度。我该怎么做?另外,我不确定如何评估特定图像/预测的显着性热图。我想我将不得不使用sess = tf.keras.backend.get_session()
and sess.run()
,但不确定。我将非常感谢任何帮助完成显着性热图代码的帮助。谢谢!
小智 5
如果将激活作为单个层添加到最后一个密集层之后:
keras.layers.Activation('softmax')
你可以做:
linear_model = keras.Model(input=model, output=model.layers[-2].output)
然后计算梯度,如下所示:
def get_saliency_map(model, image, class_idx):
with tf.GradientTape() as tape:
tape.watch(image)
predictions = model(image)
loss = predictions[:, class_idx]
# Get the gradients of the loss w.r.t to the input image.
gradient = tape.gradient(loss, image)
# take maximum across channels
gradient = tf.reduce_max(gradient, axis=-1)
# convert to numpy
gradient = gradient.numpy()
# normaliz between 0 and 1
min_val, max_val = np.min(gradient), np.max(gradient)
smap = (gradient - min_val) / (max_val - min_val + keras.backend.epsilon())
return smap
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5235 次 |
最近记录: |