神经网络模型结构和参数可视化

一、前言

在神经网络的某些应用场景中,需要将设计的网络模型结构绘制出来进行展示,或需要查看训练完成后的模型权重、偏置等参数,而由于使用训练架构的不同某些架构不提供模型可视化功能,这时就需要寻找一些工具达到可视化的目的。
这些工具大体上可分为两种,
(1)能够读取已训练好的神经网络模型,加载模型后会自动显示出模型结构、参数等信息;
(2)无法读取模型文件,需要额外提供如网络结构、权重数值等参数才能绘制出相应的模型结构,显然此种只能用于绘制结构而无法查看模型参数。

二、Netron

2.1Netron简介

Netron属于第一种能够直接读取模型文件的可视化工具,工具提供网页版和客户端版,支持Linux和Windows,网页版地址为https://netron.app/,客户端版地址为https://github.com/lutzroeder/netron/releases,目前最新版为7.6.8。
在这里插入图片描述
源码地址为https://github.com/lutzroeder/netron,经页面介绍可知,Netron支持大部分训练架构导出的模型格式,包括以下几种:
在这里插入图片描述

2.2TensorFlow、Keras、Caffe模型文件实测结果

经过实际测试,Netron可以正常显示TensorFlow、Keras、Caffe模型结构和参数,模型图如下:
TensorFlow模型文件:
在这里插入图片描述
Keras模型文件:
在这里插入图片描述
Caffe模型文件:
在这里插入图片描述

2.3PyTorch、scikit-learn模型文件实测结果

打开PyTorch模型文件,可以查看参数,但结构信息无法完全显示,模型图如下:
在这里插入图片描述
打开scikit-learn模型文件,可以查看参数,但是不显示结构信息,模型图如下:
在这里插入图片描述
综合来看,Netron功能强大,支持查看大多数类型的模型文件参数,但在模型结构可视化上还存在些不足。

三、NN-SVG

NN-SVG属于第二种工具,无法加载模型文件,只能通过设置一些参数实现模型结构的绘制。NN-SVG只有网页版,地址为https://alexlenail.me/NN-SVG/,没有客户端版。源码地址为https://github.com/alexlenail/NN-SVG
在这里插入图片描述
NN-SVG支持绘制FCNN、LeNet、AlexNet三种模型结构,结构参数通过界面而非代码设置,较其他同类工具操作更为便捷。

四、Netscope

Netscope与NN-SVG类似,同属第二种工具,但不同的是网络结构由代码进行定义,所以支持多种网络结构。Netscope通过网页提供服务,可以在线使用,也可以下载源代码后本地部署网络服务使用,在线版地址为:https://dgschwend.github.io/netscope/quickstart.html,源代码地址为:https://github.com/cwlacewe/netscope
进入在线版网页后,点击Launch Editor,在左上方输入代码。
绘制全连接神经网络结构代码如下:

name: "FCNN"

layer {
  name: "input"
  type: "Input"
  top: "data"
  input_param { shape: { dim: 1 dim: 3 dim: 1 dim: 1} }
}

layer {
  name: "fc1"
  type: "InnerProduct"
  bottom: "data"
  top: "fc1"
  inner_product_param { num_output: 10 }
}

layer {
  name: "relu1"
  type: "ReLU"
  bottom: "fc1"
  top: "fc1"
}

layer {
  name: "fc2"
  type: "InnerProduct"
  bottom: "fc1"
  top: "fc2"
  inner_product_param { num_output: 15 }
}

layer {
  name: "relu2"
  type: "ReLU"
  bottom: "fc2"
  top: "fc2"
}

layer {
  name: "fc3"
  type: "InnerProduct"
  bottom: "fc2"
  top: "fc3"
  inner_product_param { num_output: 5 }
}

layer {
  name: "softmax"
  type: "Softmax"
  bottom: "fc3"
  top: "softmax"
}

全连接神经网络结构图如下:
在这里插入图片描述
Netscope还会给出关于网络模型的分析,如下图:
在这里插入图片描述
Netscope由于使用代码定义模型结构,所以能够描绘的网络模型种类多于NN-SVG,信息也更为详细,但采用简易的二维模块框进行模型结构绘制,美观度上似乎略低于NN-SVG。

五、PlotNeuralNet

PlotNeuralNet,属于第二种工具,工作原理为通过python代码生成LaTeX文档,再由MikTeX软件对文档进行解析生成PDF格式的模型结构图。
PlotNeuralNet源代码地址为:https://github.com/HarisIqbal88/PlotNeuralNet
MikTeX软件地址为:https://miktex.org/download
使用时先将源代码下载到本地,然后参照给出的示例编写模型结构定义代码,运行代码生成LaTeX文档,使用MikTeX软件解析文档生成模型结构图。
下面为绘制LeNet模型的代码:

import sys
sys.path.append('../')
from pycore.tikzeng import *

def to_FullyConnected(name, s_filer, offset="(0,0,0)", to="(0,0,0)", width=1, height=1, depth=1, caption=" "):
    return to_Conv(name, s_filer, s_filer, offset, to, width, height, depth, caption)

# Define the architecture
arch = [
    to_head('..'),
    to_cor(),
    to_begin(),

    # Input layer
    to_input("../examples/fcn8s/cats.jpg", width=6, height=6, name="input"),

    # Convolutional Layer 1
    to_Conv(name='conv1', s_filer=28, n_filer=6, offset="(0,0,0)", to="(0,0,0)", width=2, height=28, depth=28, caption="Conv1"),
    to_Pool(name="pool1", offset="(0,0,0)", to="(conv1-east)", width=1, height=14, depth=14, caption="Pool1"),

    # Convolutional Layer 2
    to_Conv(name='conv2', s_filer=10, n_filer=16, offset="(2,0,0)", to="(pool1-east)", width=3, height=10, depth=10, caption="Conv2"),
    to_Pool(name="pool2", offset="(0,0,0)", to="(conv2-east)", width=1, height=5, depth=5, caption="Pool2"),

    # Fully Connected Layers
    to_FullyConnected(name="fc1", s_filer=120, offset="(2,0,0)", to="(pool2-east)", width=1, height=5, depth=5, caption="FC1"),
    to_FullyConnected(name="fc2", s_filer=84, offset="(1.5,0,0)", to="(fc1-east)", width=1, height=4, depth=4, caption="FC2"),

    # Output Layer
    to_SoftMax(name="output", s_filer=10, offset="(2,0,0)", to="(fc2-east)", width=1, height=3, depth=3, caption="Output"),

    # Connections
    to_connection("conv1", "pool1"),
    to_connection("pool1", "conv2"),
    to_connection("conv2", "pool2"),
    to_connection("pool2", "fc1"),
    to_connection("fc1", "fc2"),
    to_connection("fc2", "output"),

    to_end()
]

def main():
    namefile = str(sys.argv[0]).split('.')[0]
    to_generate(arch, namefile + '.tex')

if __name__ == '__main__':
    main()

下图为LeNet模型图:
在这里插入图片描述
下图为NN-SVG生成的LeNet模型图:
在这里插入图片描述
与NN-SVG相比,PlotNeuralNet生成的图片为三维立体,颜色更为鲜艳,但使用代码进行模型结构定义,操作上不如NN-SVG直观,且无法绘制全连接型神经网络。

六、Graphviz

Graphviz (Graph Visualization Software) 是一个由AT&T实验室启动的开源工具包,使用dot语言描述图形结构,可以绘制有向图、无向图、流程图、组织结构图等图形。本文基于python使用graphviz工具包,Graphviz官网地址为:https://graphviz.org/,python-graphviz库源代码地址为:https://github.com/xflr6/graphviz
使用方法如下:
首先使用pip命令安装graphviz库:

pip install graphviz

然后从Graphviz官网下载graphviz包,下载地址为https://graphviz.org/download/,本文下载的版本为Windows——graphviz-11.0.0 (64-bit) ZIP archive [sha256] (contains all tools and libraries)。下载后解压,然后将“解压路径/Graphviz-11.0.0-win64/bin”添加至环境变量中的path变量。
执行完上面两步,就可以编写python代码定义模型结构。
下面是绘制全连接神经网络的代码:

from graphviz import Digraph
def draw_FCNN():
    # 创建有向图对象
    dot = Digraph(engine='neato')

    # 定义神经网络层及其节点
    input_nodes = ['x1', 'x2', 'x3']
    hidden_nodes = ['h1', 'h2']
    output_nodes = ['o1']

    # 设置节点的位置
    input_positions = {'x1': '0,4!', 'x2': '0,2!', 'x3': '0,0!'}
    hidden_positions = {'h1': '2,3!', 'h2': '2,1!'}
    output_position = {'o1': '4,2!'}

    # 定义权重和阈值(示例)
    weights = {
        ('x1', 'h1'): 0.2, ('x1', 'h2'): 0.4,
        ('x2', 'h1'): 0.3, ('x2', 'h2'): 0.5,
        ('x3', 'h1'): 0.1, ('x3', 'h2'): 0.2,
        ('h1', 'o1'): 0.6, ('h2', 'o1'): 0.7
    }

    biases = {
        'h1': 0.1, 'h2': 0.2, 'o1': 0.3
    }

    # 添加节点并设置位置和标签
    for node, pos in input_positions.items():
        dot.node(node, label=node, shape='circle', width='1.0', style='filled', fillcolor='lightblue', pos=pos)

    for node, pos in hidden_positions.items():
        label = f'{node}\n(b={biases[node]})'
        dot.node(node, label=label, shape='circle', width='1.0', style='filled', fillcolor='lightgreen', pos=pos)

    for node, pos in output_position.items():
        label = f'{node}\n(b={biases[node]})'
        dot.node(node, label=label, shape='circle', width='1.0', style='filled', fillcolor='lightcoral', pos=pos)

    # 添加边及其权重
    for (start, end), weight in weights.items():
        dot.edge(start, end, label=f'w={weight}')

    # 渲染图表
    dot.render('simple_nn_pos', format='png', view=True)

draw_FCNN()

下图为绘制的全连接神经网络结构图:
在这里插入图片描述
下面是绘制LeNet网络结构的代码:

from graphviz import Digraph
def draw_LeNet():
    # 创建一个有向图对象
    dot = Digraph()
    dot.attr(rankdir='LR')
    dot.attr('node', shape='box3d', style='filled', fillcolor='lightblue', fontname='Helvetica')
    dot.attr('edge', arrowhead='vee', color='blue')
    
    # 添加节点
    dot.node('I', 'Input Layer\n(28x28x1)')
    dot.node('C1', 'Conv Layer 1\n(24x24x6)\n5x5 kernels')
    dot.node('P1', 'Pool Layer 1\n(12x12x6)\n2x2 avg pool')
    dot.node('C2', 'Conv Layer 2\n(8x8x16)\n5x5 kernels')
    dot.node('P2', 'Pool Layer 2\n(4x4x16)\n2x2 avg pool')
    dot.node('F1', 'Fully Connected Layer 1\n(120)')
    dot.node('F2', 'Fully Connected Layer 2\n(84)')
    dot.node('O', 'Output Layer\n(10)')

    # 添加边
    dot.edge('I', 'C1')
    dot.edge('C1', 'P1')
    dot.edge('P1', 'C2')
    dot.edge('C2', 'P2')
    dot.edge('P2', 'F1')
    dot.edge('F1', 'F2')
    dot.edge('F2', 'O')

    # 保存并渲染图表,同时删除中间文件
    dot.render('lenet_structure', format='png', view=True, cleanup=True)

draw_LeNet()

下图为LeNet网络结构图:
在这里插入图片描述
graphviz的参数释义可参照官网介绍,官网上内容较为详细,其中比较重要的一些参数如下:
1、布局引擎的指定
graphviz默认引擎为dot,在默认引擎下,会自动调整节点间距、连接线形状等参数,使用控制间距的nodesep参数起到的作用有限,当节点较多时可能会引起布局混乱。
可通过如下代码指定引擎为neato,在该引擎下可以进行节点精确定位

dot = Digraph(engine='neato')

2、pos
该参数用于指定节点的中心的位置,但在默认引擎下不会起作用,要使该参数生效,可指定引擎为neato,此时单位为英寸。另外,如果pos设置后整体布局四周出现留白,那么引擎会自动消除留白使空间布局更加合理。
3、width、height
这两个参数指定节点的高度和宽度,单位为英寸。如果设置的过小,那么节点可能会显示为实际大小而非设置的大小,可认为是设置的最小尺寸
4、dpi
该参数在graphviz中是指每英寸多少个像素,所以dpi设置的越大,得到的图像更清晰。默认dpi为96。
下面代码是设置dpi为600。

dot.attr(dpi='600')

5、size
该参数是设置生成的图像的宽度和高度,单位为英寸。当图像的实际大小小于该参数时会按照实际大小保存,大于该参数时则会被缩放,所以可认为是设置的最大尺寸
下面代码是设置图像宽度为10英寸,高度为20英寸。

dot.attr(size='10,20')

6、保存图片格式
graphviz支持导出多种格式的图片,且不限于图片,也可导出svg、pdf格式的文件。本文测试导出了三种图片格式,分别为png、bmp、jpg,导出的图片大小:bmp>png>jpg,导出速度快慢:jpg>bmp>png。
当节点数较多时,可选择jpg格式,导出快且节省存储空间。

对于绘制的全连接型神经网络,graphviz绘制的网络外观上优于NN-SVG,而且可以显示权重、偏置阈值,这个优点很突出。
对于绘制的LeNet模型,美观程度与NN-SVG各有优劣,但是略低于PlotNeuralNet。

七、总结

综合上述几种神经网络模型结构可视化工具的实际测试,汇总如下:

应用场景适合工具
查看模型内部参数Netron
绘制全连接神经网络——要求显示权重等参数Graphviz
绘制全连接神经网络——美观优先Graphviz>NN-SVG
绘制全连接神经网络——速度优先NN-SVG>Graphviz
绘制其他神经网络——美观优先PlotNeuralNet>NN-SVG>Graphviz>Netron>Netscope
绘制其他神经网络——速度优先NN-SVG>Netron>Netscope>Graphviz>PlotNeuralNet

参考文档

神经网络可视化(一)——Netron
一图抵千言 | 神经网络绘图篇!涵盖NN-SVG、PlotNeuralNet、Netron等软件!
PlotNeuralNet简单教程
如何画出漂亮的神经网络图?

  • 11
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值