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

举报
不脱发的程序猿 发表于 2021/01/01 01:07:09 2021/01/01
【摘要】 本文将展示如何利用Python中的NetworkX模块来绘制深度神经网络(DNN)结构图。 已知我们创建的DNN结构图如下: 该DNN模型由输入层、隐藏层、输出层和softmax函数组成,每一层的神经元个数分别为4,5,6,3,3。不知道聪明的读者有没有发现,这张示意图完全是由笔者自己用Python绘制出来的,因为并不存在现成的结构图。那么,如何利用Python来绘制...

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

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

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

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

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


  
  1. # -*- coding:utf-8 -*-
  2. import networkx as nx
  3. import matplotlib.pyplot as plt
  4. # 创建DAG
  5. G = nx.DiGraph()
  6. # 顶点列表
  7. vertex_list = ['v'+str(i) for i in range(1, 22)]
  8. # 添加顶点
  9. G.add_nodes_from(vertex_list)
  10. # 边列表
  11. edge_list = [
  12. ('v1', 'v5'), ('v1', 'v6'), ('v1', 'v7'),('v1', 'v8'),('v1', 'v9'),
  13. ('v2', 'v5'), ('v2', 'v6'), ('v2', 'v7'),('v2', 'v8'),('v2', 'v9'),
  14. ('v3', 'v5'), ('v3', 'v6'), ('v3', 'v7'),('v3', 'v8'),('v3', 'v9'),
  15. ('v4', 'v5'), ('v4', 'v6'), ('v4', 'v7'),('v4', 'v8'),('v4', 'v9'),
  16. ('v5','v10'),('v5','v11'),('v5','v12'),('v5','v13'),('v5','v14'),('v5','v15'),
  17. ('v6','v10'),('v6','v11'),('v6','v12'),('v6','v13'),('v6','v14'),('v6','v15'),
  18. ('v7','v10'),('v7','v11'),('v7','v12'),('v7','v13'),('v7','v14'),('v7','v15'),
  19. ('v8','v10'),('v8','v11'),('v8','v12'),('v8','v13'),('v8','v14'),('v8','v15'),
  20. ('v9','v10'),('v9','v11'),('v9','v12'),('v9','v13'),('v9','v14'),('v9','v15'),
  21. ('v10','v16'),('v10','v17'),('v10','v18'),
  22. ('v11','v16'),('v11','v17'),('v11','v18'),
  23. ('v12','v16'),('v12','v17'),('v12','v18'),
  24. ('v13','v16'),('v13','v17'),('v13','v18'),
  25. ('v14','v16'),('v14','v17'),('v14','v18'),
  26. ('v15','v16'),('v15','v17'),('v15','v18'),
  27. ('v16','v19'),
  28. ('v17','v20'),
  29. ('v18','v21')
  30. ]
  31. # 通过列表形式来添加边
  32. G.add_edges_from(edge_list)
  33. # 绘制DAG图
  34. plt.title('DNN for iris') #图片标题
  35. nx.draw(
  36. G,
  37. node_color = 'red', # 顶点颜色
  38. edge_color = 'black', # 边的颜色
  39. with_labels = True, # 显示顶点标签
  40. font_size =10, # 文字大小
  41. node_size =300 # 顶点大小
  42. )
  43. # 显示图片
  44. plt.show()

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

这显然不是我们想要的结果,因为各神经的连接情况不明朗,而且很多神经都挤在了一起,看不清楚。之所以出现这种情况,是因为我们没有给神经元设置坐标,导致每个神经元都是随机放置的。
接下来,引入坐标机制,即设置好每个神经元节点的坐标,使得它们的位置能够按照事先设置好的来放置,其Python代码如下: 


  
  1. # -*- coding:utf-8 -*-
  2. import networkx as nx
  3. import matplotlib.pyplot as plt
  4. # 创建DAG
  5. G = nx.DiGraph()
  6. # 顶点列表
  7. vertex_list = ['v'+str(i) for i in range(1, 22)]
  8. # 添加顶点
  9. G.add_nodes_from(vertex_list)
  10. # 边列表
  11. edge_list = [
  12. ('v1', 'v5'), ('v1', 'v6'), ('v1', 'v7'),('v1', 'v8'),('v1', 'v9'),
  13. ('v2', 'v5'), ('v2', 'v6'), ('v2', 'v7'),('v2', 'v8'),('v2', 'v9'),
  14. ('v3', 'v5'), ('v3', 'v6'), ('v3', 'v7'),('v3', 'v8'),('v3', 'v9'),
  15. ('v4', 'v5'), ('v4', 'v6'), ('v4', 'v7'),('v4', 'v8'),('v4', 'v9'),
  16. ('v5','v10'),('v5','v11'),('v5','v12'),('v5','v13'),('v5','v14'),('v5','v15'),
  17. ('v6','v10'),('v6','v11'),('v6','v12'),('v6','v13'),('v6','v14'),('v6','v15'),
  18. ('v7','v10'),('v7','v11'),('v7','v12'),('v7','v13'),('v7','v14'),('v7','v15'),
  19. ('v8','v10'),('v8','v11'),('v8','v12'),('v8','v13'),('v8','v14'),('v8','v15'),
  20. ('v9','v10'),('v9','v11'),('v9','v12'),('v9','v13'),('v9','v14'),('v9','v15'),
  21. ('v10','v16'),('v10','v17'),('v10','v18'),
  22. ('v11','v16'),('v11','v17'),('v11','v18'),
  23. ('v12','v16'),('v12','v17'),('v12','v18'),
  24. ('v13','v16'),('v13','v17'),('v13','v18'),
  25. ('v14','v16'),('v14','v17'),('v14','v18'),
  26. ('v15','v16'),('v15','v17'),('v15','v18'),
  27. ('v16','v19'),
  28. ('v17','v20'),
  29. ('v18','v21')
  30. ]
  31. # 通过列表形式来添加边
  32. G.add_edges_from(edge_list)
  33. # 指定绘制DAG图时每个顶点的位置
  34. pos = {
  35. 'v1':(-2,1.5),
  36. 'v2':(-2,0.5),
  37. 'v3':(-2,-0.5),
  38. 'v4':(-2,-1.5),
  39. 'v5':(-1,2),
  40. 'v6': (-1,1),
  41. 'v7':(-1,0),
  42. 'v8':(-1,-1),
  43. 'v9':(-1,-2),
  44. 'v10':(0,2.5),
  45. 'v11':(0,1.5),
  46. 'v12':(0,0.5),
  47. 'v13':(0,-0.5),
  48. 'v14':(0,-1.5),
  49. 'v15':(0,-2.5),
  50. 'v16':(1,1),
  51. 'v17':(1,0),
  52. 'v18':(1,-1),
  53. 'v19':(2,1),
  54. 'v20':(2,0),
  55. 'v21':(2,-1)
  56. }
  57. # 绘制DAG图
  58. plt.title('DNN for iris') #图片标题
  59. plt.xlim(-2.2, 2.2) #设置X轴坐标范围
  60. plt.ylim(-3, 3) #设置Y轴坐标范围
  61. nx.draw(
  62. G,
  63. pos = pos, # 点的位置
  64. node_color = 'red', # 顶点颜色
  65. edge_color = 'black', # 边的颜色
  66. with_labels = True, # 显示顶点标签
  67. font_size =10, # 文字大小
  68. node_size =300 # 顶点大小
  69. )
  70. # 显示图片
  71. plt.show()

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

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

  1. 去掉神经元节点的标签;
  2. 添加模型层的文字注释(比如Input layer).

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


  
  1. # -*- coding:utf-8 -*-
  2. import cv2
  3. import networkx as nx
  4. import matplotlib.pyplot as plt
  5. # 创建DAG
  6. G = nx.DiGraph()
  7. # 顶点列表
  8. vertex_list = ['v'+str(i) for i in range(1, 22)]
  9. # 添加顶点
  10. G.add_nodes_from(vertex_list)
  11. # 边列表
  12. edge_list = [
  13. ('v1', 'v5'), ('v1', 'v6'), ('v1', 'v7'),('v1', 'v8'),('v1', 'v9'),
  14. ('v2', 'v5'), ('v2', 'v6'), ('v2', 'v7'),('v2', 'v8'),('v2', 'v9'),
  15. ('v3', 'v5'), ('v3', 'v6'), ('v3', 'v7'),('v3', 'v8'),('v3', 'v9'),
  16. ('v4', 'v5'), ('v4', 'v6'), ('v4', 'v7'),('v4', 'v8'),('v4', 'v9'),
  17. ('v5','v10'),('v5','v11'),('v5','v12'),('v5','v13'),('v5','v14'),('v5','v15'),
  18. ('v6','v10'),('v6','v11'),('v6','v12'),('v6','v13'),('v6','v14'),('v6','v15'),
  19. ('v7','v10'),('v7','v11'),('v7','v12'),('v7','v13'),('v7','v14'),('v7','v15'),
  20. ('v8','v10'),('v8','v11'),('v8','v12'),('v8','v13'),('v8','v14'),('v8','v15'),
  21. ('v9','v10'),('v9','v11'),('v9','v12'),('v9','v13'),('v9','v14'),('v9','v15'),
  22. ('v10','v16'),('v10','v17'),('v10','v18'),
  23. ('v11','v16'),('v11','v17'),('v11','v18'),
  24. ('v12','v16'),('v12','v17'),('v12','v18'),
  25. ('v13','v16'),('v13','v17'),('v13','v18'),
  26. ('v14','v16'),('v14','v17'),('v14','v18'),
  27. ('v15','v16'),('v15','v17'),('v15','v18'),
  28. ('v16','v19'),
  29. ('v17','v20'),
  30. ('v18','v21')
  31. ]
  32. # 通过列表形式来添加边
  33. G.add_edges_from(edge_list)
  34. # 指定绘制DAG图时每个顶点的位置
  35. pos = {
  36. 'v1':(-2,1.5),
  37. 'v2':(-2,0.5),
  38. 'v3':(-2,-0.5),
  39. 'v4':(-2,-1.5),
  40. 'v5':(-1,2),
  41. 'v6': (-1,1),
  42. 'v7':(-1,0),
  43. 'v8':(-1,-1),
  44. 'v9':(-1,-2),
  45. 'v10':(0,2.5),
  46. 'v11':(0,1.5),
  47. 'v12':(0,0.5),
  48. 'v13':(0,-0.5),
  49. 'v14':(0,-1.5),
  50. 'v15':(0,-2.5),
  51. 'v16':(1,1),
  52. 'v17':(1,0),
  53. 'v18':(1,-1),
  54. 'v19':(2,1),
  55. 'v20':(2,0),
  56. 'v21':(2,-1)
  57. }
  58. # 绘制DAG图
  59. plt.title('DNN for iris') #图片标题
  60. plt.xlim(-2.2, 2.2) #设置X轴坐标范围
  61. plt.ylim(-3, 3) #设置Y轴坐标范围
  62. nx.draw(
  63. G,
  64. pos = pos, # 点的位置
  65. node_color = 'red', # 顶点颜色
  66. edge_color = 'black', # 边的颜色
  67. font_size =10, # 文字大小
  68. node_size =300 # 顶点大小
  69. )
  70. # 保存图片,图片大小为640*480
  71. plt.savefig('E://data/DNN_sketch.png')
  72. # 利用opencv模块对DNN框架添加文字注释
  73. # 读取图片
  74. imagepath = 'E://data/DNN_sketch.png'
  75. image = cv2.imread(imagepath, 1)
  76. # 输入层
  77. cv2.rectangle(image, (85, 130), (120, 360), (255,0,0), 2)
  78. cv2.putText(image, "Input Layer", (15, 390), 1, 1.5, (0, 255, 0), 2, 1)
  79. # 隐藏层
  80. cv2.rectangle(image, (190, 70), (360, 420), (255,0,0), 2)
  81. cv2.putText(image, "Hidden Layer", (210, 450), 1, 1.5, (0, 255, 0), 2, 1)
  82. # 输出层
  83. cv2.rectangle(image, (420, 150), (460, 330), (255,0,0), 2)
  84. cv2.putText(image, "Output Layer", (380, 360), 1, 1.5, (0, 255, 0), 2, 1)
  85. # sofrmax层
  86. cv2.rectangle(image, (530, 150), (570, 330), (255,0,0), 2)
  87. cv2.putText(image, "Softmax Func", (450, 130), 1, 1.5, (0, 0, 255), 2, 1)
  88. # 保存修改后的图片
  89. cv2.imwrite('E://data/DNN.png', image)

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

文章来源: handsome-man.blog.csdn.net,作者:不脱发的程序猿,版权归原作者所有,如需转载,请联系作者。

原文链接:handsome-man.blog.csdn.net/article/details/88095710

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。