类激活热力图(CAM,class activation map)
CAM,class activation map来自于论文《Learning Deep Features for Discriminative Localization》。通过based model+CAM之后,我们可以得到如下图所示的热度图,在对最后结果影响比较大的地方生成的热度就比较高。
这项技术非常有用但是存在一些缺陷的。首先我们必须改变网络结构,例如把全连接层改成全局平均池化层,这不利于训练。第二是这是基于分类问题的一种可视化技术,帮助我们更好的理解模型内部的学习情况。但是该方法用于回归问题可能就没有这么好的效果。
为了解决第一个问题,2017年出现了一种改进的技术叫Grad-CAM,Grad-CAM可以不改变网络结构进行可视化,详见这篇论文《Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization》 (2017 ICCV)。
import numpy as np import tensorflow as tf import cv2 VGG16_model = tf.keras.applications.VGG16(include_top=True) VGG16_model.summary() from tensorflow.keras.applications.vgg16 import preprocess_input, decode_predictions def prepocess(x): x = tf.io.read_file(x) x = tf.image.decode_jpeg(x, channels=3) x = tf.image.resize(x, [224,224]) x =tf.expand_dims(x, 0) # 扩维 x = preprocess_input(x) return x img_path=cat.jpg img=prepocess(img_path) Predictions = VGG16_model.predict(img, steps=1) print(Predicted:, decode_predictions(Predictions, top=3)[0]) # 应用Grad-CAM 算法 # 构建一个同时输出最后一层的卷积层和类别预测结果的网络 from tensorflow.keras import models last_conv_layer = VGG16_model.get_layer(block5_conv3) heatmap_model =models.Model([VGG16_model.inputs], [last_conv_layer.output, VGG16_model.output]) # Grad-CAM 算法实现 import tensorflow.keras.backend as K with tf.GradientTape() as gtape: conv_output, Predictions = heatmap_model(img) prob = Predictions[:, np.argmax(Predictions[0])] # 最大可能性类别的预测概率 grads = gtape.gradient(prob, conv_output) # 类别与卷积层的梯度 (1,14,14,512) pooled_grads = K.mean(grads, axis=(0,1,2)) # 特征层梯度的全局平均代表每个特征层权重 heatmap = tf.reduce_mean(tf.multiply(pooled_grads, conv_output), axis=-1) #权重与特征层相乘,512层求和平均 with tf.Session() as sess: init = tf.initialize_all_variables() sess.run(init) Predictions,heatmap = sess.run([Predictions, heatmap]) # 绘制激活热力图 heatmap = np.maximum(heatmap, 0) max_heat = np.max(heatmap) if max_heat == 0: max_heat = 1e-10 heatmap /= max_heat # plt.matshow(heatmap, cmap=viridis) original_img=cv2.imread(cat.jpg) heatmap1 = cv2.resize(heatmap[0], (original_img.shape[1], original_img.shape[0]), interpolation=cv2.INTER_CUBIC) heatmap1 = np.uint8(255*heatmap1) heatmap1 = cv2.applyColorMap(heatmap1, cv2.COLORMAP_JET) frame_out=cv2.addWeighted(original_img,0.5,heatmap1,0.5,0) cv2.imwrite(Egyptian_cat.jpg, frame_out) cv2.imwrite("heatmap.jpg", heatmap1) # 前三类结果比较 # 首先使用如下代买对预测的最大值进行修改,得到第二和第三可能性的预测结果 Predictions3=Predictions Predictions3[0][np.argmax(Predictions3[0])]=np.min(Predictions3) Predictions3[0][np.argmax(Predictions3[0])]=np.min(Predictions3)
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
算法:青蛙跳台阶问题