您的位置:首页 > 理论基础 > 计算机网络

利用Graphviz画神经网络框架图

2019-05-14 23:34 2496 查看
版权声明:本文为Edisonleejt原创文章, 转载请注明出处。 https://blog.csdn.net/Edisonleeee/article/details/90217562

文章目录

  • Python 画神经网络图
  • 前言

    做了神经网络这么久,偶尔想画一下自己模型的架构图,但是又无从下手,因为网络一般都比较复杂,如果自己手动利用Visio画的画又比较麻烦,而我又比较懒,网上搜了一下Graphviz
    画图工具,学了会便开始打算利用它来画模型结构图。
    关于Graphviz的介绍,可以参考我的前两篇博客:

    dot画神经网络图

    简单神经网络

    digraph G {
    rankdir=LR;
    splines=line;
    nodesep=.1;
    node [label=""];
    subgraph cluster_0 {
    color=white;
    node [style=solid,color=green,shape=circle];
    i;
    label = "Input Layer";
    }
    
    subgraph cluster_1 {
    color=white;
    node [style=solid,color=blue, shape=circle];
    h11, h12, h13, h14;
    label = "Hidden Layer 1";
    }
    
    subgraph cluster_2 {
    color=white;
    node [style=solid,color=blue, shape=circle];
    h21, h22;
    label = "Hidden Layer 2";
    }
    
    subgraph cluster_3 {
    color=white;
    node [style=solid,color=red, shape=circle];
    o;
    label="Output Layer";
    }
    
    i -> h11
    i -> h12
    i -> h13
    i -> h14
    
    h11 -> h21
    h11 -> h22
    h12 -> h21
    h12 -> h22
    h13 -> h21
    h13 -> h22
    h14 -> h21
    h14 -> h22
    
    h21 -> o
    h22 -> o
    
    }

    这里我们定义了一个图

    G
    ,及四个子图
    cluster_0
    cluster_1
    cluster_2
    cluster_ 3
    ,并为每个子图定义了结点类
    node
    及其各自属性,由于神经网络是全连接,因此我们需要为每一个结点连上边(十分繁琐)。
    将其保存为
    demo.dot
    文件,通过命令:
    dot -Tpng demo.dot -o demo.png

    将其转化为png图片,如下所示:

    好了,这样就画好了一个简单的神经网络模型图了,但是当你遇上结点较多的情况怎么办?
    你可能会说,我又不傻,难道一个个在dot脚本上写上去?我可以用省略号代替啊!好的,那么来试试省略号代替的“伪大型神经网络”样子。

    大型神经网络(伪)

    digraph G {
    rankdir=LR;
    splines=line;
    nodesep=.1;
    node [label=""];
    compound=true
    subgraph cluster_0 {
    color=white;
    node [style=solid,color=green,shape=circle];
    i;
    label = "Input Layer";
    }
    
    subgraph cluster_1 {
    color=white;
    node [style=solid,color=blue, shape=circle];
    h11, h12, h13, h14;
    label = "Hidden Layer 1 (4 nodes)";
    }
    
    subgraph cluster_2 {
    color=white;
    {
    node [style=solid,color=blue,shape=circle];
    h21;h22;
    }
    node [style=solid,shape=point];
    p1; p2; p3;
    {
    node [style=solid,color=blue,shape=circle];
    h23;h24;
    }
    label = "Hidden Layer 2 (100 nodes)";
    }
    
    subgraph cluster_3 {
    color=white;
    node [style=solid,color=red, shape=circle];
    o;
    label="Output Layer";
    }
    
    i -> h11
    i -> h12
    i -> h13
    i -> h14
    
    h11 -> h21
    h11 -> h22
    h12 -> h21
    h12 -> h22
    h13 -> h21
    h13 -> h22
    h14 -> h21
    h14 -> h22
    
    h11 -> h23
    h11 -> h24
    h12 -> h23
    h12 -> h24
    h13 -> h23
    h13 -> h24
    h14 -> h23
    h14 -> h24
    
    h21 -> o
    h22 -> o
    h23 -> o
    h24 -> o
    
    }


    这里我通过增加了几个形状为

    point
    的结点,使得整个网络看起来像是一个大型的网络的缩略版。注意,画图的时候顺序是按照结点定义的顺序来画的,所以三个小黑点要定义在中间。

    Python 画神经网络图

    大型神经网络

    虽然按照上面的做法能够“投机取巧”地画出一个伪大型神经网络结构图,但是当你要真正画一个大型神经网络并且观察它的连接细节呢?这种时候就要利用Python的力量了。
    代码如下,相关解释已经写在代码注释中:

    from graphviz import Digraph
    
    def Neural_Network_Graph(input_layer, hidden_layers, output_layer, filename="demo"):
    g = Digraph('g', filename=filename)  # 定义一个有向图
    n = 0  # 所有结点的数量,用其来作为结点的名字(代号)
    g.graph_attr.update(splines="false", nodesep='0.8',
    ranksep='2', rankdir="LR")
    # 设置下图的属性: 线类型,结点间隔,每一级的间隔
    
    # Input Layer
    with g.subgraph(name='cluster_input') as c:
    the_label = 'Input Layer'
    c.attr(color='white')
    for i in range(input_layer):
    n += 1
    c.node(str(n))
    c.attr(label=the_label, rank='same')
    c.node_attr.update(color="#2ecc71", style="filled",
    fontcolor="#2ecc71", shape="circle")
    
    last_layer_nodes = input_layer  # 最后一层的结点数量
    nodes_up = input_layer  # 总结点数量
    
    # Hidden Layers
    
    hidden_layers_nr = len(hidden_layers)  # 隐藏层层数
    for i in range(hidden_layers_nr):
    with g.subgraph(name="cluster_" + str(i + 1)) as c:
    c.attr(color='white')
    c.attr(rank='same')
    the_label = "Hidden Layer" + str(i+1)
    c.attr(label=the_label)
    for j in range(hidden_layers[i]):
    n += 1
    c.node(str(n), shape="circle", style="filled",
    color="#3498db", fontcolor="#3498db")
    for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1):
    g.edge(str(h), str(n))  # 定义好上一层到下一层的连接线
    last_layer_nodes = hidden_layers[i]
    nodes_up += hidden_layers[i]
    
    # Output Layer
    with g.subgraph(name='cluster_output') as c:
    c.attr(color='white')
    c.attr(rank='same')
    for i in range(1, output_layer + 1):
    n += 1
    c.node(str(n), shape="circle", style="filled",
    color="#e74c3c", fontcolor="#e74c3c")
    for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1):
    g.edge(str(h), str(n))
    c.attr(label='Output Layer')
    c.node_attr.update(color="#2ecc71", style="filled",
    fontcolor="#2ecc71", shape="circle")
    
    g.attr(arrowShape="none")
    g.edge_attr.update(arrowhead="none", color="#707070")
    g.render(filename, format="png")

    我编写了一个

    Neural_Network_Graph
    函数,接收输入为:

    • input_layer
      :输入层神经元数量
    • hidden_layers
      :列表类型,隐藏层层数及神经元数量
    • output_layer
      :输出层神经元数量
      通过定义三个参数,调用
      Neural_Network_Graph
      函数:
    # -------------------------------------------
    input_layer = 5  # 输入层的神经元数量
    hidden_layers = [10, 6]  # 隐藏层层数和数量
    output_layer = 1  # 输出层神经元数量
    # -----------------------------------------------
    
    Neural_Network_Graph(input_layer, hidden_layers, output_layer)

    很容易得到一张

    png
    格式的神经网络图:

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: