卷积神经网络(CNN)是当前深度学习中最常用的神经网络之一。在训练一个CNN模型时,我们通常会遇到一些问题,比如如何确定哪些特征在哪些卷积层被检测到、卷积层输出特征图的质量和稳定性等。在解决这些问题时,可视化卷积核和特征图是一种非常有效的方法。
本文将介绍如何使用Keras和TensorFlow在CNN中可视化卷积核和特征图。
对于卷积核的可视化,我们将使用Keras提供的backend
模块,它提供了许多操作神经网络层输出的函数。导入所需库:
from keras.models import Model
from keras.layers import Input, Conv2D, MaxPooling2D
from keras.utils import plot_model
import keras.backend as K
import numpy as np
import matplotlib.pyplot as plt
我们需要一个简单的CNN模型,以便可视化卷积核。以下是我们构建的模型:
input_img = Input(shape=(28,28,1))
x = Conv2D(32, (3,3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2,2), padding='same')(x)
x = Conv2D(64, (3,3), activation='relu', padding='same')(x)
x = MaxPooling2D((2,2), padding='same')(x)
x = Conv2D(128, (3,3), activation='relu', padding='same')(x)
model = Model(input_img, x)
这个模型包含了三个卷积层。
得到模型卷积层的权重:
weights = model.get_weights()
然后可以从权重中提取卷积核。对于Conv2D
层,卷积核通常是权重的前四个维度。因此我们可以采用如下的方式获取第一层卷积核:
W = weights[0]
在获取卷积核后,我们可以通过Matplotlib库可视化卷积核。以下是一个简单的卷积核可视化函数:
def conv_kernel(kernel, index):
fig = plt.figure(figsize=(8,8))
columns = 8
rows = 4
for i in range(columns*rows):
fig.add_subplot(rows, columns, i+1)
plt.imshow(kernel[:,:,0,i], cmap='gray')
plt.axis('off')
plt.title('Kernel ' + str(i+1))
plt.suptitle('Conv2D layer ' + str(index+1))
plt.show()
这个函数可以接受一个卷积核和卷积层的索引,然后它会绘制出该层的所有卷积核。
conv_kernel(W, 0)
我们可以看到它绘制了32个3x3的灰度图像,这些图像是第一层的32个卷积核。
通过以上步骤,我们可以轻松地可视化卷积神经网络的卷积核。值得一提的是,对于更深的模型,这个技术也同样适用。只需要将层的索引更改为所需的层,就可以轻松地进行卷积核的可视化。
除了可视化卷积核,我们还可以可视化CNN的特征图。这可以通过热度图实现。导入相应的库:
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input, decode_predictions
选择一个预训练的模型,例如VGG16:
from keras.applications.vgg16 import VGG16
model = VGG16(include_top=True, weights='imagenet')
这里我们使用的是VGG16,这个模型是ImageNet竞赛上最知名的模型之一。
然后选择一张图像,以便进行可视化:
img_path = 'elephant.jpg'
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)
使用以下命令来获取特征图:
layer_outputs = [layer.output for layer in model.layers[:8]]
activation_model = Model(inputs=model.input, outputs=layer_outputs)
activations = activation_model.predict(x)
这里我们使用的是VGG16的前8层。
以下是用于可视化特征图的代码:
def visualize_feature_map(feature_map):
fig = plt.figure(figsize=(12,12))
columns = 8
rows = 4
for i in range(columns*rows):
fig.add_subplot(rows, columns, i+1)
plt.imshow(feature_map[0,:, :, i], cmap='gray')
plt.axis('off')
plt.title('Feature map ' + str(i+1))
plt.show()
这个函数可以接受一个特定层的激活张量,然后它会绘制出该层的所有特征图。
visualize_feature_map(activations[1])
我们可以看到它绘制了第一卷积层的所有特征图。
通过以上步骤,我们可以轻松地可视化CNN的特征图。同样,对于更深的模型,这个技术也同样适用。只需要将层的索引更改为所需的层,就可以轻松地进行特征图的可视化。
该示例使用一个包含三个卷积层的CNN模型,在模型训练之前,我们可以使用conv_kernel()
函数可视化第一层的所有卷积核。
input_img = Input(shape=(28,28,1))
x = Conv2D(32, (3,3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2,2), padding='same')(x)
x = Conv2D(64, (3,3), activation='relu', padding='same')(x)
x = MaxPooling2D((2,2), padding='same')(x)
x = Conv2D(128, (3,3), activation='relu', padding='same')(x)
model = Model(input_img, x)
weights = model.get_weights()
W = weights[0]
conv_kernel(W, 0)
在运行之后,我们可以看到它绘制了32个3x3的灰度图像,这些图像是第一层的32个卷积核。
该示例使用一个预训练的VGG16模型,我们可以使用visualize_feature_map()
函数可视化该模型的第一层的所有特征图。
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input, decode_predictions
from keras.applications.vgg16 import VGG16
model = VGG16(include_top=True, weights='imagenet')
img_path = 'elephant.jpg'
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)
layer_outputs = [layer.output for layer in model.layers[:8]]
activation_model = Model(inputs=model.input, outputs=layer_outputs)
activations = activation_model.predict(x)
visualize_feature_map(activations[1])
在运行之后,我们可以看到它绘制了第一卷积层的所有特征图。
本文链接:http://task.lmcjl.com/news/16767.html