在深度学习研究中,我们对于网络模型的学习过程的认识,大多是以一个黑盒的形式呈现出来的。网络结构中卷积层通过训练数据学习到怎样的特征,特征图是什么样的,对我们而言是隐晦难懂的,为此我们可以通过可视化特征图的方法,以图片的形式将网络结构中某一层特征图显示出来,直观的展现的我们面前,以便后续深入了解这复杂的网路模型。
环境:Tensorflow1.X
需要的包:import matplotlib as plt from pylab import *
过程,首先将网络中需要可视化网络层张量返回到加载模型的验证过程的文件中,然后将运行该张量,得到numpy数组,从而显示,具体方法如下:
1.模型文件model.py
class vgg16:
def __init__(self, imgs):
self.imgs = imgs
self.convlayers()
self.fc_layers()
self.c3_3 = self.conv3_3
def saver(self):
return tf.train.Saver()
def maxpool(self, name, input_data):
out = tf.nn.max_pool(input_data,[1,2,2,1],[1,2,2,1],padding="SAME",name=name)
return out
def conv(self,name,input_data,out_channel):
in_channel = input_data.get_shape()[-1]
with tf.variable_scope(name):
kernel = tf.get_variable("weights",[3, 3, in_channel,out_channel],dtype=tf.float32)
biases = tf.get_variable("biases",[out_channel],dtype=tf.float32)
conv_res = tf.nn.conv2d(input_data, kernel, [1,1,1,1], padding="SAME")
res = tf.nn.bias_add(conv_res,biases)
out = tf.nn.leaky_relu(res, name=name)
return out
def convlayers(self):
self.conv1_1 = self.conv("conv1re_1",self.imgs,64)
self.conv1_2 = self.conv("conv1_2",self.conv1_1,64)
·
·
·
self.conv3_2 = self.conv("convrwe3_2", self.conv3_1,256)
self.conv3_3 = self.conv("convrew3_3", self.conv3_2,256)#假设需要显示该层卷积层
self.pool3 = self.maxpool("poolre3",self.conv3_3)
2加载训练模型文件Predict.py
import tensorflow as tf
import numpy as np
import VGG16_Model as model
import os
import cv2
import matplotlib as plt
from pylab import *
from scipy import misc
#####################################
def get_row_col(num_pic):
squr = num_pic ** 0.5
row = round(squr)
col = row + 1 if squr - row > 0 else row
return row, col
def visualize_feature_map(img_batch):
feature_map = np.squeeze(img_batch, axis=0)
print(feature_map.shape)
feature_map_combination = []
plt.figure()
num_pic = feature_map.shape[2]
row, col = get_row_col(num_pic)
for i in range(0, num_pic):
feature_map_split = feature_map[:, :, i]
feature_map_combination.append(feature_map_split)
plt.subplot(row, col, i + 1)
plt.imshow(feature_map_split)
axis('off')
#title('feature_map_{}'.format(i))
plt.savefig('feature_map.png')
plt.show()
def visualize_feature_map_sum(feature_batch):
'''
将每张子图进行相加
:param feature_batch:
:return:
'''
feature_map = np.squeeze(feature_batch, axis=0)
feature_map_combination = []
# 取出 featurn map 的数量
num_pic = feature_map.shape[2]
# 将 每一层卷积的特征图,拼接层 5 × 5
for i in range(0, num_pic):
feature_map_split = feature_map[:, :, i]#设置需要叠加的特征图索引位置,比如在512个特征图中将100,200中
#特征图叠加feature_map[100:200, :, i]
feature_map_combination.append(feature_map_split)
# 按照特征图 进行 叠加代码
feature_map_sum = sum(one for one in feature_map_combination)
plt.imshow(feature_map_sum)
plt.show()
################################################
pic_width,pic_height = 64,128
x = tf.placeholder(tf.float32,[None,scale_pic_height,scale_pic_width,3])
sess =tf.Session()
vgg = model.vgg16(x)
ConVis = vgg.c3_3
fc8_finetuining = vgg.probs
saver = tf.train.Saver()
print("model restoring")
#saver=tf.train.import_meta_graph('./model/epoch000601.ckpt.meta')
saver.restore(sess,"./modeldir/epoch000602.ckpt")#重点,加载模型训练文件
image_contents = tf.read_file('C:/Users/featuremap/1_3385.png')#重点,读入需要可视化显示的图片
image = tf.image.decode_jpeg(image_contents, channels=3)
image = tf.cast(image, tf.float32)
image.set_shape((scale_pic_height, scale_pic_width, 3))
image = sess.run(image)#将image的tensorr结构转化为numpy中list数据结构,需要之后喂入网络
prob=sess.run([fc8_finetuining], feed_dict = {x:[image]})#与可视化无关,显示图片预测结果
ConVis=sess.run([ConVis], feed_dict={x:[image]})#重点,运行需要可视化的某一层网络层的tensor
visualize_feature_map(ConVis)#将每个特征图单独显示
visualize_feature_map_sum(ConVis)#将特征图叠加显示
max_index = np.argmax(prob)
print("Pred:",max_index)#输出预测结构
3 总结
只需要将网络模型中需要可视化操作的某一层网络结构tensor返回,之后sess.run(),得到特征图数据,最后函数visualize_feature_map(ConVis)与 visualize_feature_map_sum(ConVis)显示。