卷积神经网络特征图可视化(自定义网络和VGG网络)

 

借助Keras和Opencv实现的神经网络中间层特征图的可视化功能,方便我们研究CNN这个黑盒子里到发生了什么。

 

自定义网络特征可视化

 

代码:

# coding: utf-8

from keras.models import Model
import cv2
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers import Activation
from pylab import *
import keras


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()

    # 各个特征图按1:1 叠加
    feature_map_sum = sum(ele for ele in feature_map_combination)
    plt.imshow(feature_map_sum)
    plt.savefig("feature_map_sum.png")


def create_model():
    model = Sequential()

    # 第一层CNN
    # 第一个参数是卷积核的数量,第二三个参数是卷积核的大小
    model.add(Convolution2D(9, 5, 5, input_shape=img.shape))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(4, 4)))

    # 第二层CNN
    model.add(Convolution2D(9, 5, 5, input_shape=img.shape))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(3, 3)))

    # 第三层CNN
    model.add(Convolution2D(9, 5, 5, input_shape=img.shape))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    # 第四层CNN
    model.add(Convolution2D(9, 3, 3, input_shape=img.shape))
    model.add(Activation('relu'))
    # model.add(MaxPooling2D(pool_size=(2, 2)))

    return model


if __name__ == "__main__":
    img = cv2.imread('001.jpg')

    model = create_model()

    img_batch = np.expand_dims(img, axis=0)
    conv_img = model.predict(img_batch)  # conv_img 卷积结果

    visualize_feature_map(conv_img)

这里定义了一个4层的卷积,每个卷积层分别包含9个卷积、Relu激活函数和尺度不等的池化操作,系数全部是随机初始化。
输入的原图如下:

 

第一层卷积后可视化的特征图:

 

所有第一层特征图1:1融合后整体的特征图:

 

第二层卷积后可视化的特征图:

 

所有第二层特征图1:1融合后整体的特征图:

 

第三层卷积后可视化的特征图:

 

所有第三层特征图1:1融合后整体的特征图:

 

第四层卷积后可视化的特征图:

 

所有第四层特征图1:1融合后整体的特征图:

从不同层可视化出来的特征图大概可以总结出一点规律:

  • 1. 浅层网络提取的是纹理、细节特征
  • 2. 深层网络提取的是轮廓、形状、最强特征(如猫的眼睛区域)
  • 3. 浅层网络包含更多的特征,也具备提取关键特征(如第一组特征图里的第4张特征图,提取出的是猫眼睛特征)的能力
  • 4. 相对而言,层数越深,提取的特征越具有代表性
  • 5. 图像的分辨率是越来越小的

 

 

VGG19网络特征可视化

 

代码:

# coding: utf-8
from keras.applications.vgg19 import VGG19
from keras.preprocessing import image
from keras.applications.vgg19 import preprocess_input
from keras.models import Model
import numpy as np
import matplotlib.pyplot as plt
from pylab import *


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 = img_batch
    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')

    plt.savefig('feature_map.png')
    plt.show()

    # 各个特征图按1:1 叠加
    feature_map_sum = sum(ele for ele in feature_map_combination)
    plt.imshow(feature_map_sum)
    plt.savefig("feature_map_sum.png")


if __name__ == "__main__":
    base_model = VGG19(weights='imagenet', include_top=False)
    # model = Model(inputs=base_model.input, outputs=base_model.get_layer('block1_pool').output)
    # model = Model(inputs=base_model.input, outputs=base_model.get_layer('block2_pool').output)
    # model = Model(inputs=base_model.input, outputs=base_model.get_layer('block3_pool').output)
    # model = Model(inputs=base_model.input, outputs=base_model.get_layer('block4_pool').output)
    model = Model(inputs=base_model.input, outputs=base_model.get_layer('block5_pool').output)

    img_path = '001.jpg'
    img = image.load_img(img_path)
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    block_pool_features = model.predict(x)
    print(block_pool_features.shape)

    feature = block_pool_features.reshape(block_pool_features.shape[1:])

    visualize_feature_map(feature)

 

从第一到第五层的特征图分别如下:

 

从第一层到第五层各特征图按1:1比例融合后特征依次为:

<think>好的,我现在需要回答用户关于如何用代码绘制卷积神经网络(CNN)结构图的问题。用户希望得到示例代码,涵盖卷积层、池化层、全连接层的可视化,并且可能需要生成结构图的方法。根据用户提供的引用内容,尤其是引用[3],里面提到了使用Python调用LaTeX输出PDF,以及PlotNeuralNet这个工具在Ubuntu下运行正常,但在Windows下可能有问题。此外,用户还提到可能需要自己画图或用PPT,但更倾向于代码生成。 首先,我需要确定用户的需求是生成CNN的结构图,最好是代码实现的。根据引用[3],PlotNeuralNet是一个可行的工具,虽然用户提到代码有点复杂,但可能还是需要给出具体的步骤示例。另外,引用[3]中提到在Windows下可能报错,需要提醒用户注意系统环境。 接下来,我应该考虑用户可能对Python库不熟悉,需要提供安装步骤简单的示例代码。除了PlotNeuralNet,可能还有其他库如Keras的plot_model或第三方库如Netron,这些可能更简单。例如,Keras的plot_model可以直接生成模型结构图,不需要复杂的代码,适合快速可视化。 然后,我需要分步骤回答:首先介绍PlotNeuralNet的使用,包括安装、示例代码,并指出可能的问题;然后介绍Keras的plot_model方法,因为更简单,适合大部分用户;最后可能提到其他工具如NN-SVG或Netron作为备选方案。 还要注意用户提到的结构图需要包含卷积层、池化层、全连接层,所以在示例代码中需要构建这样的模型,并展示如何可视化。例如,用Keras定义一个简单的CNN模型,然后调用plot_model生成图片。 另外,用户的问题中可能隐含了如何将结构图导出为PDF或其他格式,所以需要说明生成的文件类型,比如PDF或PNG。 需要检查引用内容中的信息是否正确,比如引用[3]提到的PlotNeuralNet的使用方法,是否需要克隆项目并拼接模块,可能需要详细说明步骤。同时,引用[2]中的VGG16结构可能作为示例,但用户需要的是生成结构图的代码,所以可能不需要深入讨论VGG16的结构,而是利用其作为例子展示如何绘制。 最后,生成相关问题,可能需要围绕工具选择、不同库的优缺点、调试安装问题、自定义结构图的方法等方面提问。 总结回答结构: 1. 使用PlotNeuralNet的步骤示例代码,指出系统兼容性问题。 2. 使用Keras的plot_model方法,更简单,适合快速生成。 3. 其他工具如NN-SVG或Netron的简介。 4. 相关问题部分,涉及工具对比、安装问题、扩展应用等。</think>### 如何用代码绘制卷积神经网络架构图 #### 1. 使用 `PlotNeuralNet`(基于LaTeX生成PDF) **步骤**: 1. **安装依赖**:需安装LaTeX环境(如TeX Live)及Python包`PlotNeuralNet`。 ```bash git clone https://github.com/HarisIqbal88/PlotNeuralNet.git cd PlotNeuralNet pip install -r requirements.txt ``` 2. **编写代码**:创建`.py`文件定义网络结构模块(如`examples/example.py`): ```python from pycore.tikzeng import * arch = [ to_head('..'), to_conv('conv1', 64, 3, offset="(0,0,0)", to="(0,0,0)", height=32, depth=32, width=3), to_pool('pool1', offset="(1,0,0)", to="(conv1-east)"), to_conv('conv2', 128, 3, offset="(2,0,0)", to="(pool1-east)", height=28, depth=28, width=6), to_connection("pool1", "conv2"), to_softmax('fc1', 1000, "(5,0,0)", "(conv2-east)", caption="全连接层"), ] to_generate(arch, 'network.tex') ``` 3. **生成PDF**:编译LaTeX文件生成结构图: ```bash pdflatex network.tex ``` **注意**:此工具在Ubuntu兼容性更好,Windows需配置WSL或Docker[^3]。 --- #### 2. 使用 `keras.utils.plot_model`(快速生成图片) **步骤**: 1. **安装TensorFlow/Keras**: ```bash pip install tensorflow ``` 2. **定义模型并绘图**: ```python from tensorflow.keras import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten from tensorflow.keras.utils import plot_model model = Sequential([ Conv2D(64, (3,3), activation='relu', input_shape=(224,224,3), name='卷积层1'), MaxPooling2D((2,2), name='池化层1'), Conv2D(128, (3,3), activation='relu', name='卷积层2'), Flatten(), Dense(1000, activation='softmax', name='全连接层') ]) plot_model(model, to_file='cnn.png', show_shapes=True) ``` **输出**:生成PNG图片,展示层间连接与参数维度[^2]。 --- #### 3. 其他工具 - **NN-SVG**:在线工具,可手动调整层参数并导出SVG。 - **Netron**:支持加载模型文件(如ONNX、H5)直接可视化结构,无需代码。 ---
评论 74
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值