keras CNN卷积核可视化,热度图教程


Posted in Python onJune 22, 2020

卷积核可视化

import matplotlib.pyplot as plt
import numpy as np
from keras import backend as K
from keras.models import load_model

# 将浮点图像转换成有效图像
def deprocess_image(x):
 # 对张量进行规范化
 x -= x.mean()
 x /= (x.std() + 1e-5)
 x *= 0.1
 x += 0.5
 x = np.clip(x, 0, 1)
 # 转化到RGB数组
 x *= 255
 x = np.clip(x, 0, 255).astype('uint8')
 return x

# 可视化滤波器
def kernelvisual(model, layer_target=1, num_iterate=100):
 # 图像尺寸和通道
 img_height, img_width, num_channels = K.int_shape(model.input)[1:4]
 num_out = K.int_shape(model.layers[layer_target].output)[-1]

 plt.suptitle('[%s] convnet filters visualizing' % model.layers[layer_target].name)

 print('第%d层有%d个通道' % (layer_target, num_out))
 for i_kernal in range(num_out):
  input_img = model.input
  # 构建一个损耗函数,使所考虑的层的第n个滤波器的激活最大化,-1层softmax层
  if layer_target == -1:
   loss = K.mean(model.output[:, i_kernal])
  else:
   loss = K.mean(model.layers[layer_target].output[:, :, :, i_kernal]) # m*28*28*128
  # 计算图像对损失函数的梯度
  grads = K.gradients(loss, input_img)[0]
  # 效用函数通过其L2范数标准化张量
  grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
  # 此函数返回给定输入图像的损耗和梯度
  iterate = K.function([input_img], [loss, grads])
  # 从带有一些随机噪声的灰色图像开始
  np.random.seed(0)
  # 随机图像
  # input_img_data = np.random.randint(0, 255, (1, img_height, img_width, num_channels)) # 随机
  # input_img_data = np.zeros((1, img_height, img_width, num_channels)) # 零值
  input_img_data = np.random.random((1, img_height, img_width, num_channels)) * 20 + 128. # 随机灰度
  input_img_data = np.array(input_img_data, dtype=float)
  failed = False
  # 运行梯度上升
  print('####################################', i_kernal + 1)
  loss_value_pre = 0
  # 运行梯度上升num_iterate步
  for i in range(num_iterate):
   loss_value, grads_value = iterate([input_img_data])
   if i % int(num_iterate/5) == 0:
    print('Iteration %d/%d, loss: %f' % (i, num_iterate, loss_value))
    print('Mean grad: %f' % np.mean(grads_value))
    if all(np.abs(grads_val) < 0.000001 for grads_val in grads_value.flatten()):
     failed = True
     print('Failed')
     break
    if loss_value_pre != 0 and loss_value_pre > loss_value:
     break
    if loss_value_pre == 0:
     loss_value_pre = loss_value
    # if loss_value > 0.99:
    #  break
   input_img_data += grads_value * 1 # e-3
  img_re = deprocess_image(input_img_data[0])
  if num_channels == 1:
   img_re = np.reshape(img_re, (img_height, img_width))
  else:
   img_re = np.reshape(img_re, (img_height, img_width, num_channels))
  plt.subplot(np.ceil(np.sqrt(num_out)), np.ceil(np.sqrt(num_out)), i_kernal + 1)
  plt.imshow(img_re) # , cmap='gray'
  plt.axis('off')

 plt.show()

运行

model = load_model('train3.h5')
kernelvisual(model,-1) # 对最终输出可视化
kernelvisual(model,6) # 对第二个卷积层可视化

keras CNN卷积核可视化,热度图教程

keras CNN卷积核可视化,热度图教程

热度图

import cv2
import matplotlib.pyplot as plt
import numpy as np
from keras import backend as K
from keras.preprocessing import image

def heatmap(model, data_img, layer_idx, img_show=None, pred_idx=None):
 # 图像处理
 if data_img.shape.__len__() != 4:
  # 由于用作输入的img需要预处理,用作显示的img需要原图,因此分开两个输入
  if img_show is None:
   img_show = data_img
  # 缩放
  input_shape = K.int_shape(model.input)[1:3]  # (28,28)
  data_img = image.img_to_array(image.array_to_img(data_img).resize(input_shape))
  # 添加一个维度->(1, 224, 224, 3)
  data_img = np.expand_dims(data_img, axis=0)
 if pred_idx is None:
  # 预测
  preds = model.predict(data_img)
  # 获取最高预测项的index
  pred_idx = np.argmax(preds[0])
 # 目标输出估值
 target_output = model.output[:, pred_idx]
 # 目标层的输出代表各通道关注的位置
 last_conv_layer_output = model.layers[layer_idx].output
 # 求最终输出对目标层输出的导数(优化目标层输出),代表目标层输出对结果的影响
 grads = K.gradients(target_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([data_img])
 # 将各通道关注的位置和各通道的影响乘起来
 for i in range(conv_layer_output_value.shape[-1]):
  conv_layer_output_value[:, :, i] *= pooled_grads_value[i]

 # 对各通道取平均得图片位置对结果的影响
 heatmap = np.mean(conv_layer_output_value, axis=-1)
 # 规范化
 heatmap = np.maximum(heatmap, 0)
 heatmap /= np.max(heatmap)
 # plt.matshow(heatmap)
 # plt.show()
 # 叠加图片
 # 缩放成同等大小
 heatmap = cv2.resize(heatmap, (img_show.shape[1], img_show.shape[0]))
 heatmap = np.uint8(255 * heatmap)
 # 将热图应用于原始图像.由于opencv热度图为BGR,需要转RGB
 superimposed_img = img_show + cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)[:,:,::-1] * 0.4
 # 截取转uint8
 superimposed_img = np.minimum(superimposed_img, 255).astype('uint8')
 return superimposed_img, heatmap
 # 显示图片
 # plt.imshow(superimposed_img)
 # plt.show()
 # 保存为文件
 # superimposed_img = img + cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) * 0.4
 # cv2.imwrite('ele.png', superimposed_img)

# 生成所有卷积层的热度图
def heatmaps(model, data_img, img_show=None):
 if img_show is None:
  img_show = np.array(data_img)
 # Resize
 input_shape = K.int_shape(model.input)[1:3] # (28,28,1)
 data_img = image.img_to_array(image.array_to_img(data_img).resize(input_shape))
 # 添加一个维度->(1, 224, 224, 3)
 data_img = np.expand_dims(data_img, axis=0)
 # 预测
 preds = model.predict(data_img)
 # 获取最高预测项的index
 pred_idx = np.argmax(preds[0])
 print("预测为:%d(%f)" % (pred_idx, preds[0][pred_idx]))
 indexs = []
 for i in range(model.layers.__len__()):
  if 'conv' in model.layers[i].name:
   indexs.append(i)
 print('模型共有%d个卷积层' % indexs.__len__())
 plt.suptitle('heatmaps for each conv')
 for i in range(indexs.__len__()):
  ret = heatmap(model, data_img, indexs[i], img_show=img_show, pred_idx=pred_idx)
  plt.subplot(np.ceil(np.sqrt(indexs.__len__()*2)), np.ceil(np.sqrt(indexs.__len__()*2)), i*2 + 1)\
   .set_title(model.layers[indexs[i]].name)
  plt.imshow(ret[0])
  plt.axis('off')
  plt.subplot(np.ceil(np.sqrt(indexs.__len__()*2)), np.ceil(np.sqrt(indexs.__len__()*2)), i*2 + 2)\
   .set_title(model.layers[indexs[i]].name)
  plt.imshow(ret[1])
  plt.axis('off')
 plt.show()

运行

from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input

model = VGG16(weights='imagenet')
data_img = image.img_to_array(image.load_img('elephant.png'))
# VGG16预处理:RGB转BGR,并对每一个颜色通道去均值中心化
data_img = preprocess_input(data_img)
img_show = image.img_to_array(image.load_img('elephant.png'))

heatmaps(model, data_img, img_show)

elephant.png

keras CNN卷积核可视化,热度图教程

keras CNN卷积核可视化,热度图教程

结语

踩坑踩得我脚疼

以上这篇keras CNN卷积核可视化,热度图教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python文件与目录操作实例详解
Feb 22 Python
Python线程指南详细介绍
Jan 05 Python
详解PyTorch批训练及优化器比较
Apr 28 Python
Python基于win32ui模块创建弹出式菜单示例
May 09 Python
对python的文件内注释 help注释方法
May 23 Python
漂亮的Django Markdown富文本app插件的实现
Jan 02 Python
python实现图片压缩代码实例
Aug 12 Python
如何基于python操作json文件获取内容
Dec 24 Python
torch 中各种图像格式转换的实现方法
Dec 26 Python
Python 跨.py文件调用自定义函数说明
Jun 01 Python
解析Python 偏函数用法全方位实现
Jun 26 Python
Python集合set()使用的方法详解
Mar 18 Python
python实现斗地主分牌洗牌
Jun 22 #Python
解决Keras使用GPU资源耗尽的问题
Jun 22 #Python
Keras - GPU ID 和显存占用设定步骤
Jun 22 #Python
Python 基于jwt实现认证机制流程解析
Jun 22 #Python
python中format函数如何使用
Jun 22 #Python
Tensorflow与Keras自适应使用显存方式
Jun 22 #Python
python数据类型强制转换实例详解
Jun 22 #Python
You might like
php5 pdo新改动加载注意事项
2008/09/11 PHP
PHP中读写文件实现代码
2011/10/20 PHP
PHPExcel读取Excel文件的实现代码
2011/12/06 PHP
Zend的AutoLoad机制介绍
2012/09/27 PHP
ThinkPHP3.1查询语言详解
2014/06/19 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
tp5框架的增删改查操作示例
2019/10/31 PHP
网页设计常用的一些技巧
2006/12/22 Javascript
对字符串进行HTML编码和解码的JavaScript函数
2010/02/01 Javascript
一个JavaScript函数把URL参数解析成Json对象
2014/09/24 Javascript
jq实现左侧显示图片右侧文字滑动切换效果
2015/08/04 Javascript
jQuery实现带延迟的二级tab切换下拉列表效果
2015/09/01 Javascript
再谈javascript注入 黑客必备!
2016/09/14 Javascript
Kendo Grid editing 自定义验证报错提示的解决方法
2016/11/18 Javascript
浅谈js原生拖放
2016/11/21 Javascript
微信小程序 下拉菜单的实现
2017/04/06 Javascript
基于jQuery实现的Ajax 验证用户名唯一性实例代码
2017/06/28 jQuery
解决微信浏览器缓存站点入口文件(IIS部署Vue项目)
2019/06/17 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
微信小程序实现身份证取景框拍摄
2020/09/09 Javascript
python查找指定具有相同内容文件的方法
2015/06/28 Python
Mac下Anaconda的安装和使用教程
2018/11/29 Python
对Python3之进程池与回调函数的实例详解
2019/01/22 Python
超简单使用Python换脸实例
2019/03/27 Python
python中struct模块之字节型数据的处理方法
2019/08/27 Python
解决pycharm启动后总是不停的updating indices...indexing的问题
2019/11/27 Python
基于Python3.7.1无法导入Numpy的解决方式
2020/03/09 Python
python dict乱码如何解决
2020/06/07 Python
退休感言
2014/01/28 职场文书
安卓程序员求职信
2014/02/28 职场文书
高一军训决心书
2015/02/05 职场文书
心灵点滴观后感
2015/06/02 职场文书
永远是春天观后感
2015/06/12 职场文书
创业计划书之零食店(进口)
2019/09/24 职场文书
在CSS中使用when/else的方法
2022/01/18 HTML / CSS
Java处理延时任务的常用几种解决方案
2022/06/01 Java/Android