利用CNN制作热力图heatmap
我们用的model是vgg16 vgg16的下载地址: 其结构如下,可以看到我们input这个模型中的图片大小应该为224*224的: 这是我们要用到的原图:
运行代码如下:
from keras.applications.vgg16 import VGG16 from keras import backend as K K.clear_session() model = VGG16(weights=./vgg16_weights_tf_dim_ordering_tf_kernels.h5) model.summary() from keras.preprocessing import image from keras.applications.vgg16 import preprocess_input, decode_predictions import numpy as np # 此处是导入你想处理的照片的地址(如果照片和vgg16文件还有你写的代码文件在同一个存储路径的话,此处只需要写照片的名称) img_path = creative_commons_elephant.jpg # 此处的target_size只能是224*224的,因为vgg16模型的结构中,规定的导入图片的大小就是224*224的 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) #调用vgg16模型 preds = model.predict(x) print(Predicted:, decode_predictions(preds, top=3)[0]) print(np.argmax(preds[0])) #这行代码的解释是:大象这个图像分类位于vgg16这个模型中的第386个索引位置上 #也就是说如果你input的图像是其他的动物,这个386这个值你是需要自己去改的,就按照上面print(np.argmax(preds[0]))代码输出的值去改就可以了 african_elephant_output = model.output[:, 386] # 看我上面的vgg16模型的结构图,这行代码意思是获取最后一个卷积层的信息(经过验证,获取最后一个卷积层的信息是最好的) last_conv_layer = model.get_layer(block5_conv3) grads = K.gradients(african_elephant_output, last_conv_layer.output)[0] pooled_grads = K.mean(grads, axis=(0, 1, 2)) iterate = K.function([model.input], [pooled_grads, last_conv_layer.output[0]]) pooled_grads_value, conv_layer_output_value = iterate([x]) #这行代码我们可以理解为:获取最后一个卷积层的512个通道的信息,并把这些信息存储在一个列表里 for i in range(512): conv_layer_output_value[:, :, i] *= pooled_grads_value[i] #此处是导入matplotlib模块如果不成功的话,你可以按照这三行代码来import matpotlib import matplotlib matplotlib.use(Agg) from matplotlib import pyplot as plt #这里你可以理解为是取倒数第二层的那512个通道信息的均值 heatmap = np.mean(conv_layer_output_value, axis=-1) #这里你可以print一下heatmap,会输出14个数组,每个数组有14个元素 print(heatmap)
输出应该是这样的:
#这三行代码你运行出来,应该是能看到一张14*14的图片 plt.matshow(heatmap) plt.savefig(bob1.png) plt.show()
由此我们可以得知:倒数第二层的那512个通道的信息取均值,输出14个数组,每个数组有14个元素,就代表一个14*14的图片,图片的每一个小格子代表数组中的每一个元素
#这两行代码的意思是:取14*14 这192个数字中的最大值,然后每个数字除以这个最大值。 heatmap = np.maximum(heatmap, 0) heatmap /= np.max(heatmap) #这三行代码的意思是把数组转换为图片输出,图片的名字你自己定 plt.matshow(heatmap) plt.savefig(bob.png) plt.show()
输出的图片应该是这样的:
import cv2 # 用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(23.jpg, superimposed_img)
如果你上面的vgg16模型运行通过了,你可以试一下用vgg19模型
可以参考我写的总结: 相信看到这里你已经对热力图制作有了一个比较透彻的理解。欢迎你把这个博客转载给更多需要的人。
上一篇:
Java架构师技术进阶路线图
下一篇:
各种复杂网络处理工具