【快速实践】类激活图(CAM,class activation map)可视化
创作时间:
作者:
@小白创作中心
【快速实践】类激活图(CAM,class activation map)可视化
引用
CSDN
1.
https://blog.csdn.net/CODE_RabbitV/article/details/144913934
类激活图(Class Activation Map,CAM)可视化技术是一种帮助理解卷积神经网络(CNN)分类决策过程的重要工具。通过生成类激活热力图,我们可以直观地看到图像中哪些区域对最终分类决策起到了关键作用。本文将详细介绍如何使用Grad-CAM算法实现这一技术,并通过代码示例展示具体实现过程。
类激活图可视化:有助于了解一张图像的哪一部分让卷积神经网络做出了最终的分类决策
- 对输入图像生成类激活热力图
- 类激活热力图是与特定输出类别相关的二维分数网格:对任何输入图像的每个位置都要进行计算,它表示每个位置对该类别的重要程度
我们将使用的具体实现方式是“Grad-CAM: visual explanations from deep networks via gradient based localization”
- 给定一张输入图像,对于一个卷积层的输出特征图,用类别相对于通道的梯度对这个特征图中的每个通道进行加权
1. 加载VGG16模型并进行图像分类
from keras.preprocessing import image
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input, decode_predictions
import numpy as np
from keras import backend as K
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
##---------------------------------- 加载 VGG16 网络
model = VGG16(weights='imagenet')
##---------------------------------- 预测给定图片
img_path = 'elephant.png'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)
##---------------------------------- 解读预测结果
print('Predicted:', decode_predictions(preds, top=3)[0])
# 打印出:对这张图像预测的前三个类别
# Predicted:', [(u'n02504458', u'African_elephant', 0.92546833), ## 非洲象(African elephant,92.5% 的概率)
# (u'n01871265', u'tusker', 0.070257246), ## 长牙动物(tusker,7%的概率)
# (u'n02504013', u'Indian_elephant', 0.0042589349)] ## 印度象(Indian elephant,0.4% 的概率)
print(np.argmax(preds[0]))
# 获得 非洲象对应输出索引:386
2. 应用Grad-CAM算法计算类激活热力图
african_elephant_output = model.output[:, 386] # 预测向量中的 “非洲象” 元素 (None,)
last_conv_layer_output = model.get_layer('block5_conv3').output # VGG16 最后一个卷积层 (None, 14, 14, 512)
# 类别相对于通道的梯度: “非洲象”类别相对于 block5_conv3 输出特征图的梯度
grads = K.gradients(african_elephant_output, last_conv_layer_output)[0] # grads.shape: (None, 14, 14, 512)
pooled_grads = K.mean(grads, axis=(0, 1, 2)) # pooled_grads.shape: (512,)
# 获得当前图 conv_layer_output_value 和 pooled_grads_value 实际值
iterate = K.function([model.input],
[pooled_grads, last_conv_layer_output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x])
# 计算加权值
for i in range(512):
conv_layer_output_value[:, :, i] *= pooled_grads_value[i]
heatmap = np.mean(conv_layer_output_value, axis=-1)
3. 可视化结果
import matplotlib.pyplot as plt
heatmap = np.maximum(heatmap, 0)
heatmap /= np.max(heatmap)
plt.matshow(heatmap)
plt.show() ## ---------------------------------------------------- 下方左图
# 缩放 heatmap 后,在原图上叠加显示
import cv2
img = cv2.imread(img_path)
heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
superimposed_img = heatmap * 0.4 + img
cv2.imwrite('elephant_cam.jpg', superimposed_img) ## -------------- 下方右图
完整代码
from keras.preprocessing import image
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input, decode_predictions
import numpy as np
from keras import backend as K
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
##---------------------------------- 加载 VGG16 网络
model = VGG16(weights='imagenet')
##---------------------------------- 预测给定图片
img_path = 'elephant.png'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)
##---------------------------------- 解读预测结果
print('Predicted:', decode_predictions(preds, top=3)[0])
# 打印出:对这张图像预测的前三个类别
# Predicted:', [(u'n02504458', u'African_elephant', 0.92546833), ## 非洲象(African elephant,92.5% 的概率)
# (u'n01871265', u'tusker', 0.070257246), ## 长牙动物(tusker,7%的概率)
# (u'n02504013', u'Indian_elephant', 0.0042589349)] ## 印度象(Indian elephant,0.4% 的概率)
print(np.argmax(preds[0]))
# 获得 非洲象对应输出索引:386
african_elephant_output = model.output[:, 386] # 预测向量中的 “非洲象” 元素 (None,)
last_conv_layer_output = model.get_layer('block5_conv3').output # VGG16 最后一个卷积层 (None, 14, 14, 512)
# 类别相对于通道的梯度: “非洲象”类别相对于 block5_conv3 输出特征图的梯度
grads = K.gradients(african_elephant_output, last_conv_layer_output)[0] # grads.shape: (None, 14, 14, 512)
pooled_grads = K.mean(grads, axis=(0, 1, 2)) # pooled_grads.shape: (512,)
# 获得当前图 conv_layer_output_value 和 pooled_grads_value 实际值
iterate = K.function([model.input],
[pooled_grads, last_conv_layer_output[0]])
pooled_grads_value, conv_layer_output_value = iterate([x])
# 计算加权值
for i in range(512):
conv_layer_output_value[:, :, i] *= pooled_grads_value[i]
heatmap = np.mean(conv_layer_output_value, axis=-1)
import matplotlib.pyplot as plt
heatmap = np.maximum(heatmap, 0)
heatmap /= np.max(heatmap)
plt.matshow(heatmap)
# plt.show()
# 缩放 heatmap 后,在原图上叠加显示
import cv2
img = cv2.imread(img_path)
heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))
heatmap = np.uint8(255 * heatmap)
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
superimposed_img = heatmap * 0.4 + img
cv2.imwrite('elephant_cam.jpg', superimposed_img)
参考书籍:Python 深度学习
热门推荐
阳江东平大澳渔村电音节:美食美景与音乐的完美邂逅
冬日打卡:广州长隆必玩景点大揭秘!
如何在家轻松炒出美味牛肉的技巧与注意事项
重温经典:《僵尸先生》同名游戏推荐
林正英的九叔:一个道士,一个时代
春节广东游:强冷空气来袭,琼州海峡大雾预警!
2025春节打卡:广州深圳必玩景点大揭秘!
广东春节必打卡:行花街
揭秘《僵尸先生》:林正英、许冠英和李赛凤的幕后故事
温州三日游必打卡:最美路线大揭秘!
温州最美古村落:林坑、黄林、黄檀硐
留胡子热潮:为什么欧美人更青睐?东亚人却不跟风?
五行与健康:《黄帝内经》思想在幼儿园的实践探索
雁荡山徒步攻略:秋冬最美路线大揭秘!
探秘雁荡山:自然奇观与人文历史的完美结合
金姓男孩名字出自古诗
什么花代表我爱你?如何用花卉表达爱意?
探访温州百年老店:三姐妹炊饭&县前汤圆店
温州必打卡!鱼丸&糯米饭哪家强?
春节机票优惠大揭秘:平台A vs 平台B
林冲妻子的最终命运:真相与传说的探讨
机票预订省钱攻略:提前21天+周二周日订票最划算
蓝哥教你7招买到便宜机票!
赣州宋潮不夜城全攻略:景点、活动、美食一网打尽
探访江西百强区:赣州宋潮不夜城
宋潮不夜城:郁孤台下的穿越之旅
宋潮不夜城:打卡赣州必玩景点!
缓解恶心小妙招:吃动按三步走!
吃姜真的能缓解恶心吗?
国家级地质公园:汤山方山地质公园,值得到此一游