Tensorflow2.0 卷积神经网络可视化 (三)类激活热力图 (CAM,class activation map)

在神经网络分别中,我们不仅想知道最终预测结果,还需要了解网络是凭借图像什么特征进行判断的。其中类激活热力图 (CAM,class activation map)就是一种很好的呈现方式。

类激活热力图 (CAM,class activation map)

导入ImageNet VGG16网络

导入基础包

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

导入ImageNet VGG16网络

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)

VGG16预测类别

对图像进行预测,并输出前3的最大可能类别

Predictions = VGG16_model.predict(img)
print('Predicted:', decode_predictions(Predictions, top=3)[0])

预测结果可以看出都是猫星人

Predicted: [('n02124075', 'Egyptian_cat', 0.49206516), ('n02123045', 'tabby', 0.21459927), ('n02123159', 'tiger_cat', 0.050253313)]

好奇在网上找了三种猫对应的图
Egyptian_cat
在这里插入图片描述
Tabby
在这里插入图片描述
Tiger_cat
在这里插入图片描述
总体上还是挺相似的,尤其是头部。接着康康三类对应的类激活热力图

应用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.GradientTape() as有问题可参考:with tf.GradientTape() as tape 梯度带 Tensorflow自动求导API

绘制激活热力图

heatmap = tf.reduce_mean(tf.multiply(pooled_grads, conv_output), axis=-1)
heatmap = np.maximum(heatmap, 0)
max_heat = np.max(heatmap)
if max_heat == 0:
    max_heat = 1e-10
heatmap /= max_heat
plt.matshow(heatmap[0], cmap='viridis')

与原有图片进行加权叠加

import cv2
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)

plt.figure()
plt.imshow(frame_out)

前三类结果比较

首先使用如下代买对预测的最大值进行修改,得到第二和第三可能性的预测结果

Predictions3=Predictions.numpy()
Predictions3[0][np.argmax(Predictions3[0])]=np.min(Predictions3)
Predictions3[0][np.argmax(Predictions3[0])]=np.min(Predictions3)

Egyptian_cat
在这里插入图片描述
Tabby
在这里插入图片描述
Tigger_cat
在这里插入图片描述
首先我个人是看不是这只猫星人是什么品种的,既然网络能辨别就让我们那看看它是依据什么做出的判断。
对于Egyptian_cat,网络比较关注猫的耳朵的特征;
对于Tabby, 网络比较关注猫的眼部的特征;
对于Tigger_cat, 网络比较关注猫的嘴和身上斑纹的特征;

参考

《Deep Learning with Python》
Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页