Illustrations by tEn

♚ \

Author: Jclian, like algorithms, love to share, hope to make more like-minded friends, together in the path of learning Python further!

Welcome to join this activity!

This article shows how to use the NetworkX module in Python to plot deep neural network (DNN) structures. \

It is known that the DNN structure diagram we created is as follows:

DNN structure diagram

The DNN model consists of input layer, hidden layer, output layer and softmax function, and the number of neurons in each layer is 4,5,6,3,3 respectively. I don’t know if the smart reader has noticed that this diagram was drawn entirely by the author himself in Python, because no ready-made structure exists. So how do you use Python to map this relatively complex neural network? The answer is to use the NetworkX module.

NetworkX is a graph theory and complex network modeling tool developed in Python language. It has built-in common graph and complex network analysis algorithm, which can easily analyze complex network data and simulate modeling. NetworkX supports the creation of simple undirected graph, directed graph and multiple graph, built-in many standard graph theory algorithm, node can be arbitrary data, support arbitrary boundary value dimension, rich function, easy to use.

First, we need to draw the outline of the DNN, with the following Python code:

# -*- coding:utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# to create DAG
G = nx.DiGraph()

# vertex list
vertex_list = ['v'+str(i) for i in range(1.22)]
# add vertex
G.add_nodes_from(vertex_list)

# edge 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')]# Add edges via a list
G.add_edges_from(edge_list)

# Draw a DAG diagram
plt.title('DNN for iris')    # Image caption

nx.draw(
        G,
        node_color = 'red'.# vertex color
        edge_color = 'black'.# Edge color
        with_labels = True.# display vertex tags
        font_size =10.# text size
        node_size =300                  # vertex size
       )
# display images
plt.show()
Copy the code

As you can see, we’ve already set up the 22 neurons and the connections between them in our code, but the resulting structure looks something like this:

DNN structure diagram with no location indicated

This is obviously not what we want, because the connections between the nerves are not clear, and many nerves are crowded together, so it’s hard to see. This happens because we don’t have coordinates for the neurons, so each neuron is randomly placed. Next, the coordinate mechanism is introduced, that is, the coordinates of each neuron node are set so that their positions can be placed according to the preset position. The Python code is as follows:

# -*- coding:utf-8 -*-
import networkx as nx
import matplotlib.pyplot as plt

# to create DAG
G = nx.DiGraph()

# vertex list
vertex_list = ['v'+str(i) for i in range(1.22)]
# add vertex
G.add_nodes_from(vertex_list)

# edge 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')]# Add edges via a list
G.add_edges_from(edge_list)

# specify the position of each vertex when drawing the DAG graph
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)}# Draw a DAG diagram
plt.title('DNN for iris')    # Image caption
plt.xlim(-2.2.2.2)                     # set the X coordinate range
plt.ylim(-3.3)                     # set the Y coordinate range
nx.draw(
        G,
        pos = pos,                      # position of point
        node_color = 'red'.# vertex color
        edge_color = 'black'.# Edge color
        with_labels = True.# display vertex tags
        font_size =10.# text size
        node_size =300                  # vertex size
       )
# display images
plt.show()
Copy the code

It can be seen that in the code, the position of each neuron node has been defined through the POS dictionary, so the DNN structure diagram drawn is as follows:

Block diagram of DNN model

As you can see, the structure of the DNN model is now roughly in place. Next, we need to make more detailed modifications to this frame diagram. The modifications are as follows:

  1. Remove labels of neuron nodes;
  2. Add text annotations for the model layer (such as Input layer).

Among them, the second step of the text annotation, we use OpencV to complete. The complete Python code is as follows:

# -*- coding:utf-8 -*-
import cv2
import networkx as nx
import matplotlib.pyplot as plt

# to create DAG
G = nx.DiGraph()

# vertex list
vertex_list = ['v'+str(i) for i in range(1.22)]
# add vertex
G.add_nodes_from(vertex_list)

# edge 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')]# Add edges via a list
G.add_edges_from(edge_list)

# specify the position of each vertex when drawing the DAG graph
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)}# Draw a DAG diagram
plt.title('DNN for iris')    # Image caption
plt.xlim(-2.2.2.2)                     # set the X coordinate range
plt.ylim(-3.3)                     # set the Y coordinate range
nx.draw(
        G,
        pos = pos,                      # position of point
        node_color = 'red'.# vertex color
        edge_color = 'black'.# Edge color
        font_size =10.# text size
        node_size =300                  # vertex size
       )

# Save the image, the image size is 640 x 480
plt.savefig('E://data/DNN_sketch.png')

# Use opencV module to add text annotations to DNN framework

# fetch image
imagepath = 'E://data/DNN_sketch.png'
image = cv2.imread(imagepath, 1)

# input layer
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)

# hidden layer
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)

# output layer
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 layer
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)

# Save the modified image
cv2.imwrite('E://data/DNN.png', image)
Copy the code

The resulting picture is the schematic diagram of DNN structure given at the beginning of the article. Bingo, done!

\

Book delivery: Long press and scan the qr code below to fill in the questionnaire on the use of the deep Learning platform for developers. Five developers will be selected from those who fill in the questionnaire to give a book of “Efficient Python Development Practice” for free. See the book introduction below and the prize will be provided by Publishing House of Electronics Industry.

* * * *

\

Python provides an in-depth insight into the wizarding world of Harry Potter. Deep copy and shallow copy problems in Python are described in Cookie and Session

Click below to read the original article

Free to become a community registered member, members can enjoy more rights and interests