在本文中,将探讨如何构建一个卷积神经网络(CNN)模型,并分析其特征图。这不仅涉及到模型的构建,还包括了对模型中间层输出的理解。目标是创建一个多类别模型,包含三个类别,并检查其特征图,而不是模型的准确度。
首先,创建一个包含三个类别的多类别模型。模型由多个卷积层、最大池化层、全连接层以及最终的输出层组成。以下是模型构建的代码示例:
model=tf.keras.models.Sequential([
tf.keras.layers.Conv2D(8,(3,3),activation ='relu', input_shape=(150,150,3)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(16,(3,3),activation ='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(32,(3,3),activation ='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(1024,activation='relu'),
tf.keras.layers.Dense(512,activation='relu'),
tf.keras.layers.Dense(3,activation='softmax')
])
模型概要显示了三个卷积层后跟最大池化层,两个全连接层,以及一个最终输出的全连接层。重要的是,需要编译并拟合模型,以便生成特征图。
要生成特征图,需要了解如何访问CNN的中间层。以下是获取CNN层名称的代码示例:
layer_names = [layer.name for layer in model.layers]
这将输出层的名称列表,例如:['conv2d', 'max_pooling2d', 'conv2d_1', 'max_pooling2d_1', 'conv2d_2', 'max_pooling2d_2', 'flatten', 'dense', 'dense_1', 'dense_2']。
接下来,需要获取CNN层的输出。以下是获取层输出的代码示例:
layer_outputs = [layer.output for layer in model.layers]
这将返回层的输出对象,它们不是实际的输出,但告诉将生成输出的函数。将这些输出对象整合到一个可视化模型中,以提取特征图。
为了生成特征图,需要构建一个可视化模型,该模型以图像为输入,并具有上述层输出作为输出函数。以下是构建特征图可视化模型的代码示例:
feature_map_model = tf.keras.models.Model(input=model.input, output=layer_outputs)
这个公式将CNN模型的输入和输出函数结合起来。总共有10个输出函数,图像作为输入,然后通过这些10个输出函数依次传递。
现在,将准备一个图像作为上述特征图模型的输入。以下是加载和预处理图像的代码示例:
image_path= r"path of the image from desktop or internet."
img = load_img(image_path, target_size=(150, 150))
input = img_to_array(img)
input = x.reshape((1,) + x.shape)
input /= 255.0
在上述代码中,将图像加载到变量“input”中,将其转换为数组,扩展图像的维度以匹配中间层的维度,并在将图像输入到层之前对其进行缩放。
最后,将图像输入到模型中,生成特征图。以下是生成特征图的代码示例:
feature_maps = feature_map_model.predict(input)
上述代码最终为生成了特征图。将再次解码特征图的内容。
现在,将检查每个输出的特征图的形状。以下是检查特征图形状的代码示例:
for layer_name, feature_map in zip(layer_names, feature_maps):
print(f"The shape of the {layer_name} is =======>> {feature_map.shape}")
上述代码将给出CNN模型中间层的层名称和生成的特征图的形状。
需要生成卷积层的特征图,而不是密集层,因此将生成具有“维度=4”的层的特征图。以下是生成特征图的代码示例:
for layer_name, feature_map in zip(layer_names, feature_maps):
if len(feature_map.shape) == 4
每个特征图都有n个通道,这个数字“n”在特征图形状的末尾给出。这是特定层中的特征数量。例如,feature_map[0].shape = (1,148,148,8)。这意味着这是一个具有8个维度的图像。因此,需要遍历这个图像以分离其8个图像。这表明layer_1输出有8个特征,这些特征被组合成1个图像。
直接生成的特征图非常暗淡,对人眼不可见。因此,需要对提取的特征图进行标准化和归一化。以下是标准化和归一化图像的代码示例:
feature_image-= feature_image.mean()
feature_image/= feature_image.std ()
feature_image*= 64
feature_image+= 128
feature_image= np.clip(x, 0, 255).astype('uint8')
scale = 20. / k
plt.figure( figsize=(scale * k, scale) )
plt.title ( layer_name )
plt.grid ( False )
plt.imshow( image_belt, aspect='auto')