使用NetworkX绘制深度神经网络结构图(Python)

简介: 使用NetworkX绘制深度神经网络结构图(Python)

本文将展示如何利用Python中的NetworkX模块来绘制深度神经网络(DNN)结构图。


已知我们创建的DNN结构图如下:

image.png



该DNN模型由输入层、隐藏层、输出层和softmax函数组成,每一层的神经元个数分别为4,5,6,3,3。不知道聪明的读者有没有发现,这张示意图完全是由笔者自己用Python绘制出来的,因为并不存在现成的结构图。那么,如何利用Python来绘制出这种相对复杂的神经网络的示意图呢?答案是利用NetworkX模块。


NetworkX是一个用Python语言开发的图论与复杂网络建模工具,内置了常用的图与复杂网络分析算法,可以方便地进行复杂网络数据分析、仿真建模等工作。NetworkX支持创建简单无向图、有向图和多重图,内置许多标准的图论算法,节点可为任意数据,支持任意的边值维度,功能丰富,简单易用。


首先,我们需要绘制出该DNN的大致框架,其Python代码如下:


# -*- coding:utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt
# 创建DAG
G = nx.DiGraph()
# 顶点列表
vertex_list = ['v'+str(i) for i in range(1, 22)]
# 添加顶点
G.add_nodes_from(vertex_list)
# 边列表
edge_list = [
             ('v1', 'v5'), ('v1', 'v6'), ('v1', 'v7'),('v1', 'v8'),('v1', 'v9'),
             ('v2', 'v5'), ('v2', 'v6'), ('v2', 'v7'),('v2', 'v8'),('v2', 'v9'),
             ('v3', 'v5'), ('v3', 'v6'), ('v3', 'v7'),('v3', 'v8'),('v3', 'v9'),
             ('v4', 'v5'), ('v4', 'v6'), ('v4', 'v7'),('v4', 'v8'),('v4', 'v9'),
             ('v5','v10'),('v5','v11'),('v5','v12'),('v5','v13'),('v5','v14'),('v5','v15'),
             ('v6','v10'),('v6','v11'),('v6','v12'),('v6','v13'),('v6','v14'),('v6','v15'),
             ('v7','v10'),('v7','v11'),('v7','v12'),('v7','v13'),('v7','v14'),('v7','v15'),
             ('v8','v10'),('v8','v11'),('v8','v12'),('v8','v13'),('v8','v14'),('v8','v15'),
             ('v9','v10'),('v9','v11'),('v9','v12'),('v9','v13'),('v9','v14'),('v9','v15'),
             ('v10','v16'),('v10','v17'),('v10','v18'),
             ('v11','v16'),('v11','v17'),('v11','v18'),
             ('v12','v16'),('v12','v17'),('v12','v18'),
             ('v13','v16'),('v13','v17'),('v13','v18'),
             ('v14','v16'),('v14','v17'),('v14','v18'),
             ('v15','v16'),('v15','v17'),('v15','v18'),
             ('v16','v19'),
             ('v17','v20'),
             ('v18','v21')
            ]
# 通过列表形式来添加边
G.add_edges_from(edge_list)
# 绘制DAG图
plt.title('DNN for iris')    #图片标题
nx.draw(
        G,
        node_color = 'red',             # 顶点颜色
        edge_color = 'black',           # 边的颜色
        with_labels = True,             # 显示顶点标签
        font_size =10,                  # 文字大小
        node_size =300                  # 顶点大小
       )
# 显示图片
plt.show()

可以看到,我们在代码中已经设置好了这22个神经元以及它们之间的连接情况,但绘制出来的结构如却是这样的:

image.png



这显然不是我们想要的结果,因为各神经的连接情况不明朗,而且很多神经都挤在了一起,看不清楚。之所以出现这种情况,是因为我们没有给神经元设置坐标,导致每个神经元都是随机放置的。

接下来,引入坐标机制,即设置好每个神经元节点的坐标,使得它们的位置能够按照事先设置好的来放置,其Python代码如下:


# -*- coding:utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt
# 创建DAG
G = nx.DiGraph()
# 顶点列表
vertex_list = ['v'+str(i) for i in range(1, 22)]
# 添加顶点
G.add_nodes_from(vertex_list)
# 边列表
edge_list = [
             ('v1', 'v5'), ('v1', 'v6'), ('v1', 'v7'),('v1', 'v8'),('v1', 'v9'),
             ('v2', 'v5'), ('v2', 'v6'), ('v2', 'v7'),('v2', 'v8'),('v2', 'v9'),
             ('v3', 'v5'), ('v3', 'v6'), ('v3', 'v7'),('v3', 'v8'),('v3', 'v9'),
             ('v4', 'v5'), ('v4', 'v6'), ('v4', 'v7'),('v4', 'v8'),('v4', 'v9'),
             ('v5','v10'),('v5','v11'),('v5','v12'),('v5','v13'),('v5','v14'),('v5','v15'),
             ('v6','v10'),('v6','v11'),('v6','v12'),('v6','v13'),('v6','v14'),('v6','v15'),
             ('v7','v10'),('v7','v11'),('v7','v12'),('v7','v13'),('v7','v14'),('v7','v15'),
             ('v8','v10'),('v8','v11'),('v8','v12'),('v8','v13'),('v8','v14'),('v8','v15'),
             ('v9','v10'),('v9','v11'),('v9','v12'),('v9','v13'),('v9','v14'),('v9','v15'),
             ('v10','v16'),('v10','v17'),('v10','v18'),
             ('v11','v16'),('v11','v17'),('v11','v18'),
             ('v12','v16'),('v12','v17'),('v12','v18'),
             ('v13','v16'),('v13','v17'),('v13','v18'),
             ('v14','v16'),('v14','v17'),('v14','v18'),
             ('v15','v16'),('v15','v17'),('v15','v18'),
             ('v16','v19'),
             ('v17','v20'),
             ('v18','v21')
            ]
# 通过列表形式来添加边
G.add_edges_from(edge_list)
# 指定绘制DAG图时每个顶点的位置
pos = {
        'v1':(-2,1.5),
        'v2':(-2,0.5),
        'v3':(-2,-0.5),
        'v4':(-2,-1.5),
        'v5':(-1,2),
        'v6': (-1,1),
        'v7':(-1,0),
        'v8':(-1,-1),
        'v9':(-1,-2),
        'v10':(0,2.5),
        'v11':(0,1.5),
        'v12':(0,0.5),
        'v13':(0,-0.5),
        'v14':(0,-1.5),
        'v15':(0,-2.5),
        'v16':(1,1),
        'v17':(1,0),
        'v18':(1,-1),
        'v19':(2,1),
        'v20':(2,0),
        'v21':(2,-1)
       }
# 绘制DAG图
plt.title('DNN for iris')    #图片标题
plt.xlim(-2.2, 2.2)                     #设置X轴坐标范围
plt.ylim(-3, 3)                     #设置Y轴坐标范围
nx.draw(
        G,
        pos = pos,                      # 点的位置
        node_color = 'red',             # 顶点颜色
        edge_color = 'black',           # 边的颜色
        with_labels = True,             # 显示顶点标签
        font_size =10,                  # 文字大小
        node_size =300                  # 顶点大小
       )
# 显示图片
plt.show()

可以看到,在代码中,通过pos字典已经规定好了每个神经元节点的位置,那么,绘制好的DNN结构示意图如下:

image.png



可以看到,现在这个DNN模型的结构已经大致显现出来了。接下来,我们需要对这个框架图进行更为细致地修改,需要修改的地方为:


去掉神经元节点的标签;

添加模型层的文字注释(比如Input layer).

其中,第二步的文字注释,我们借助opencv来完成。完整的Python代码如下:


# -*- coding:utf-8 -*-
import cv2
import networkx as nx
import matplotlib.pyplot as plt
# 创建DAG
G = nx.DiGraph()
# 顶点列表
vertex_list = ['v'+str(i) for i in range(1, 22)]
# 添加顶点
G.add_nodes_from(vertex_list)
# 边列表
edge_list = [
             ('v1', 'v5'), ('v1', 'v6'), ('v1', 'v7'),('v1', 'v8'),('v1', 'v9'),
             ('v2', 'v5'), ('v2', 'v6'), ('v2', 'v7'),('v2', 'v8'),('v2', 'v9'),
             ('v3', 'v5'), ('v3', 'v6'), ('v3', 'v7'),('v3', 'v8'),('v3', 'v9'),
             ('v4', 'v5'), ('v4', 'v6'), ('v4', 'v7'),('v4', 'v8'),('v4', 'v9'),
             ('v5','v10'),('v5','v11'),('v5','v12'),('v5','v13'),('v5','v14'),('v5','v15'),
             ('v6','v10'),('v6','v11'),('v6','v12'),('v6','v13'),('v6','v14'),('v6','v15'),
             ('v7','v10'),('v7','v11'),('v7','v12'),('v7','v13'),('v7','v14'),('v7','v15'),
             ('v8','v10'),('v8','v11'),('v8','v12'),('v8','v13'),('v8','v14'),('v8','v15'),
             ('v9','v10'),('v9','v11'),('v9','v12'),('v9','v13'),('v9','v14'),('v9','v15'),
             ('v10','v16'),('v10','v17'),('v10','v18'),
             ('v11','v16'),('v11','v17'),('v11','v18'),
             ('v12','v16'),('v12','v17'),('v12','v18'),
             ('v13','v16'),('v13','v17'),('v13','v18'),
             ('v14','v16'),('v14','v17'),('v14','v18'),
             ('v15','v16'),('v15','v17'),('v15','v18'),
             ('v16','v19'),
             ('v17','v20'),
             ('v18','v21')
            ]
# 通过列表形式来添加边
G.add_edges_from(edge_list)
# 指定绘制DAG图时每个顶点的位置
pos = {
        'v1':(-2,1.5),
        'v2':(-2,0.5),
        'v3':(-2,-0.5),
        'v4':(-2,-1.5),
        'v5':(-1,2),
        'v6': (-1,1),
        'v7':(-1,0),
        'v8':(-1,-1),
        'v9':(-1,-2),
        'v10':(0,2.5),
        'v11':(0,1.5),
        'v12':(0,0.5),
        'v13':(0,-0.5),
        'v14':(0,-1.5),
        'v15':(0,-2.5),
        'v16':(1,1),
        'v17':(1,0),
        'v18':(1,-1),
        'v19':(2,1),
        'v20':(2,0),
        'v21':(2,-1)
       }
# 绘制DAG图
plt.title('DNN for iris')    #图片标题
plt.xlim(-2.2, 2.2)                     #设置X轴坐标范围
plt.ylim(-3, 3)                     #设置Y轴坐标范围
nx.draw(
        G,
        pos = pos,                      # 点的位置
        node_color = 'red',             # 顶点颜色
        edge_color = 'black',           # 边的颜色
        font_size =10,                  # 文字大小
        node_size =300                  # 顶点大小
       )
# 保存图片,图片大小为640*480
plt.savefig('E://data/DNN_sketch.png')
# 利用opencv模块对DNN框架添加文字注释
# 读取图片
imagepath = 'E://data/DNN_sketch.png'
image = cv2.imread(imagepath, 1)
# 输入层
cv2.rectangle(image, (85, 130), (120, 360), (255,0,0), 2)
cv2.putText(image, "Input Layer", (15, 390), 1, 1.5, (0, 255, 0), 2, 1)
# 隐藏层
cv2.rectangle(image, (190, 70), (360, 420), (255,0,0), 2)
cv2.putText(image, "Hidden Layer", (210, 450), 1, 1.5, (0, 255, 0), 2, 1)
# 输出层
cv2.rectangle(image, (420, 150), (460, 330), (255,0,0), 2)
cv2.putText(image, "Output Layer", (380, 360), 1, 1.5, (0, 255, 0), 2, 1)
# sofrmax层
cv2.rectangle(image, (530, 150), (570, 330), (255,0,0), 2)
cv2.putText(image, "Softmax Func", (450, 130), 1, 1.5, (0, 0, 255), 2, 1)
# 保存修改后的图片
cv2.imwrite('E://data/DNN.png', image)

这样生成的图片就是文章最开始给出的DNN的结构示意图。Bingo,搞定!


相关文章
|
12天前
|
机器学习/深度学习 存储 算法
回声状态网络(Echo State Networks,ESN)详细原理讲解及Python代码实现
本文详细介绍了回声状态网络(Echo State Networks, ESN)的基本概念、优点、缺点、储层计算范式,并提供了ESN的Python代码实现,包括不考虑和考虑超参数的两种ESN实现方式,以及使用ESN进行时间序列预测的示例。
28 4
回声状态网络(Echo State Networks,ESN)详细原理讲解及Python代码实现
|
4天前
|
机器学习/深度学习 资源调度 自然语言处理
不同类型的循环神经网络结构
【8月更文挑战第16天】
12 0
|
12天前
|
数据采集 自然语言处理 监控
【优秀python毕设案例】基于python django的新媒体网络舆情数据爬取与分析
本文介绍了一个基于Python Django框架开发的新媒体网络舆情数据爬取与分析系统,该系统利用Scrapy框架抓取微博热搜数据,通过SnowNLP进行情感分析,jieba库进行中文分词处理,并以图表和词云图等形式进行数据可视化展示,以实现对微博热点话题的舆情监控和分析。
【优秀python毕设案例】基于python django的新媒体网络舆情数据爬取与分析
|
3天前
|
JSON API 数据格式
Python网络编程:HTTP请求(requests模块)
在现代编程中,HTTP请求几乎无处不在。无论是数据抓取、API调用还是与远程服务器进行交互,HTTP请求都是不可或缺的一部分。在Python中,requests模块被广泛认为是发送HTTP请求的最简便和强大的工具之一。本文将详细介绍requests模块的功能,并通过一个综合示例展示其应用。
|
2天前
|
数据采集 存储 中间件
Python进行网络爬虫:Scrapy框架的实践
【8月更文挑战第17天】网络爬虫是自动化程序,用于从互联网收集信息。Python凭借其丰富的库和框架成为构建爬虫的首选语言。Scrapy作为一款流行的开源框架,简化了爬虫开发过程。本文介绍如何使用Python和Scrapy构建简单爬虫:首先安装Scrapy,接着创建新项目并定义爬虫,指定起始URL和解析逻辑。运行爬虫可将数据保存为JSON文件或存储到数据库。此外,Scrapy支持高级功能如中间件定制、分布式爬取、动态页面渲染等。在实践中需遵循最佳规范,如尊重robots.txt协议、合理设置爬取速度等。通过本文,读者将掌握Scrapy基础并了解如何高效地进行网络数据采集。
24 6
|
4天前
|
设计模式 开发者 索引
Python中的分支结构
Python中的分支结构
|
11天前
|
机器学习/深度学习 算法 文件存储
【博士每天一篇文献-算法】 PNN网络启发的神经网络结构搜索算法Progressive neural architecture search
本文提出了一种名为渐进式神经架构搜索(Progressive Neural Architecture Search, PNAS)的方法,它使用顺序模型优化策略和替代模型来逐步搜索并优化卷积神经网络结构,从而提高了搜索效率并减少了训练成本。
20 9
|
12天前
|
机器学习/深度学习 前端开发 数据挖掘
基于Python Django的房价数据分析平台,包括大屏和后台数据管理,有线性、向量机、梯度提升树、bp神经网络等模型
本文介绍了一个基于Python Django框架开发的房价数据分析平台,该平台集成了多种机器学习模型,包括线性回归、SVM、GBDT和BP神经网络,用于房价预测和市场分析,同时提供了前端大屏展示和后台数据管理功能。
|
6天前
|
机器学习/深度学习 人工智能 PyTorch
AI智能体研发之路-模型篇(五):pytorch vs tensorflow框架DNN网络结构源码级对比
AI智能体研发之路-模型篇(五):pytorch vs tensorflow框架DNN网络结构源码级对比
20 1
|
12天前
|
机器学习/深度学习 数据可视化 Python
如何可视化神经网络的神经元节点之间的连接?附有Python预处理代码
该博客展示了如何通过Python预处理神经网络权重矩阵并将其导出为表格,然后使用Chiplot网站来可视化神经网络的神经元节点之间的连接。
19 0
如何可视化神经网络的神经元节点之间的连接?附有Python预处理代码