1 用到的方法:
tf.io.decode_image(
contents, #将要解码为张量的对象
channels=None, #设置通道数
dtype=tf.dtypes.uint8, #数据类型
name=None,
expand_animations=True#控制返回的数据形状3D/4D
)
zip(iterator,strict=False) #在多个迭代器上并行迭代,从每个迭代器返回一个数据项组成元组,迭代对象长度不同时,迭代完成最短的即可。
2 详细代码
这里是在模型训练好的基础上进行的,所以才有model.predict
#展示特征图
import os
import numpy as np
import random
from PIL import Image
from PIL import ImageShow
#import tensorflow as tf
import matplotlib.pyplot as plt
train_horse_dir="E:/pycharmProject/horse-or-human/horses/" #存放horse的路径
train_human_dir="E:/pycharmProject/horse-or-human/humans/" #存放human的路径
layer_output=[layer.output for layer in model.layers]
visualization_model=tf.keras.models.Model(inputs=model.input,outputs=layer_output)
horse_img_files=[os.path.join(train_horse_dir,f) for f in os.listdir(train_horse_dir)]
human_img_files=[os.path.join(train_human_dir,f) for f in os.listdir(train_human_dir)]
horse_human_dir=horse_img_files+human_img_files
img_path=random.choice(horse_human_dir)
print(img_path)
#image=Image.open(img_path)
#ImageShow.show(image) #打开图片,以本机默认方式打开
image=plt.imread(img_path)
plt.axis('off')
plt.imshow(image)
img=tf.io.read_file(img_path)
'''tf.io.decode_image(
contents,
channels=None,
dtype=tf.dtypes.uint8,
name=None,
expand_animations=True
)'''
img_tensor=tf.image.decode_image(img,channels=3)
img_tensor=img_tensor/255
imgs=tf.image.resize(img_tensor,[64,64])
img_final=np.expand_dims(imgs,axis=0)
#img_tensor.reshape((1,)+img_tensor.shape)
feature_maps=visualization_model.predict(img_final)#共有7层每层对应一个'大图',每个大图由多个子特征图构成
layer_names=[layer.name for layer in model.layers]
for layer_name,feature_map in zip(layer_names,feature_maps):
#zip(iterator,strict=False)在多个迭代器上并行迭代,从每个迭代器返回一个数据项组成元组,
#迭代对象长度不同时,迭代完成最短的即可。
if len(feature_map.shape)==4:
#feature_map.shape=(1,size,size,feature_nums)
feature_nums=feature_map.shape[-1]
print(feature_nums)
size=feature_map.shape[1]
display_map=np.zeros((size,size*feature_nums)) #显示时高为一个子特征图的高,宽为所有子特征图宽的和
for i in range(feature_nums):
x=feature_map[0,:,:,i]#第i个特征图
#下面前两步数据标准化,为了实现中心化处理,使其更符合数据分布规律
x=x-x.mean()
x=x/x.std()
x=x*64
x=x+128
x=np.clip(x,0,255).astype('uint8')
#clip(a,a_min,a_max,out=None)将数组a的值限制到区间[a_min,a_max]
#astype(dtype)转换数据类型为dtype
display_map[:,i*size:(i+1)*size]=x #切片将x赋值到设定位置,将第i个子图放到位置i*size:(i+1)*size的区间
scale=15
plt.figure(figsize=(scale,scale/feature_nums)) #设置显示的画布尺寸
plt.title(layer_name)
#plt.grid(False) #配置网格线,这里不显示坐标轴,不用设置
plt.axis('off') #不显示坐标轴
plt.imshow(display_map,aspect='auto',cmap='viridis')#aspect:auto坐标轴纵横比设置为自动调整
#cmap='viridis' 将标量数据映射到颜色,默认'viridis'
3 结果
这是作者的学习笔记,在此分享,仅供参考。因为作者水平有限,如有疏漏之处,还望批评指正。