使用NetworkX模塊繪制深度神經(jīng)網(wǎng)絡(luò)(DNN)結(jié)構(gòu)圖

??本文將展示如何利用Python中的NetworkX模塊來繪制深度神經(jīng)網(wǎng)絡(luò)(DNN)結(jié)構(gòu)圖。
??在文章Keras入門(一)搭建深度神經(jīng)網(wǎng)絡(luò)(DNN)解決多分類問題中花鹅,我們創(chuàng)建的DNN結(jié)構(gòu)圖如下:

DNN結(jié)構(gòu)示意圖

該DNN模型由輸入層、隱藏層减余、輸出層和softmax函數(shù)組成累驮,每一層的神經(jīng)元個數(shù)分別為4,5,6,3,3。不知道聰明的讀者有沒有發(fā)現(xiàn)煎饼,這張示意圖完全是由筆者自己用Python繪制出來的讹挎,因為并不存在現(xiàn)成的結(jié)構(gòu)圖。那么,如何利用Python來繪制出這種相對復(fù)雜的神經(jīng)網(wǎng)絡(luò)的示意圖呢淤袜?答案是利用NetworkX模塊痒谴。

NetworkX是一個用Python語言開發(fā)的圖論與復(fù)雜網(wǎng)絡(luò)建模工具,內(nèi)置了常用的圖與復(fù)雜網(wǎng)絡(luò)分析算法铡羡,可以方便地進行復(fù)雜網(wǎng)絡(luò)數(shù)據(jù)分析积蔚、仿真建模等工作。NetworkX支持創(chuàng)建簡單無向圖烦周、有向圖和多重圖尽爆,內(nèi)置許多標準的圖論算法,節(jié)點可為任意數(shù)據(jù)读慎,支持任意的邊值維度漱贱,功能豐富,簡單易用夭委。

??首先幅狮,我們需要繪制出該DNN的大致框架,其Python代碼如下:

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

# 創(chuàng)建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()

可以看到株灸,我們在代碼中已經(jīng)設(shè)置好了這22個神經(jīng)元以及它們之間的連接情況崇摄,但繪制出來的結(jié)構(gòu)如卻是這樣的:

未標明位置的DNN結(jié)構(gòu)圖

這顯然不是我們想要的結(jié)果,因為各神經(jīng)的連接情況不明朗慌烧,而且很多神經(jīng)都擠在了一起逐抑,看不清楚。之所以出現(xiàn)這種情況屹蚊,是因為我們沒有給神經(jīng)元設(shè)置坐標厕氨,導(dǎo)致每個神經(jīng)元都是隨機放置的。
??接下來汹粤,引入坐標機制命斧,即設(shè)置好每個神經(jīng)元節(jié)點的坐標,使得它們的位置能夠按照事先設(shè)置好的來放置玄括,其Python代碼如下:

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

# 創(chuàng)建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)                     #設(shè)置X軸坐標范圍
plt.ylim(-3, 3)                     #設(shè)置Y軸坐標范圍
nx.draw(
        G,
        pos = pos,                      # 點的位置
        node_color = 'red',             # 頂點顏色
        edge_color = 'black',           # 邊的顏色
        with_labels = True,             # 顯示頂點標簽
        font_size =10,                  # 文字大小
        node_size =300                  # 頂點大小
       )
# 顯示圖片
plt.show()

可以看到冯丙,在代碼中,通過pos字典已經(jīng)規(guī)定好了每個神經(jīng)元節(jié)點的位置遭京,那么胃惜,繪制好的DNN結(jié)構(gòu)示意圖如下:

DNN模型的框架圖

可以看到,現(xiàn)在這個DNN模型的結(jié)構(gòu)已經(jīng)大致顯現(xiàn)出來了哪雕。
??接下來船殉,我們需要對這個框架圖進行更為細致地修改,需要修改的地方為:

  1. 去掉神經(jīng)元節(jié)點的標簽斯嚎;
  2. 添加模型層的文字注釋(比如Input layer).

其中利虫,第二步的文字注釋挨厚,我們借助opencv來完成。完整的Python代碼如下:

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

# 創(chuàng)建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)                     #設(shè)置X軸坐標范圍
plt.ylim(-3, 3)                     #設(shè)置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的結(jié)構(gòu)示意圖疫剃。Bingo,搞定!

注意:本人現(xiàn)已開通微信公眾號: Python爬蟲與算法(微信號為:easy_web_scrape)硼讽, 歡迎大家關(guān)注哦~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巢价,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子固阁,更是在濱河造成了極大的恐慌壤躲,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件备燃,死亡現(xiàn)場離奇詭異碉克,居然都是意外死亡,警方通過查閱死者的電腦和手機并齐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門漏麦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冀膝,你說我怎么就攤上這事唁奢。” “怎么了窝剖?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長酥夭。 經(jīng)常有香客問我赐纱,道長,這世上最難降的妖魔是什么熬北? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任疙描,我火速辦了婚禮,結(jié)果婚禮上讶隐,老公的妹妹穿的比我還像新娘起胰。我一直安慰自己,他們只是感情好巫延,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布效五。 她就那樣靜靜地躺著,像睡著了一般炉峰。 火紅的嫁衣襯著肌膚如雪畏妖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天疼阔,我揣著相機與錄音戒劫,去河邊找鬼半夷。 笑死,一個胖子當(dāng)著我的面吹牛迅细,可吹牛的內(nèi)容都是我干的巫橄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼茵典,長吁一口氣:“原來是場噩夢啊……” “哼嗦随!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起敬尺,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤枚尼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后砂吞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體署恍,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年蜻直,在試婚紗的時候發(fā)現(xiàn)自己被綠了盯质。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡概而,死狀恐怖呼巷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赎瑰,我是刑警寧澤王悍,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站餐曼,受9級特大地震影響压储,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜源譬,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一集惋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧踩娘,春花似錦刮刑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至厚脉,卻和暖如春习寸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背傻工。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工霞溪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留孵滞,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓鸯匹,卻偏偏與公主長得像坊饶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子殴蓬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 離我家一個街口的位置匿级,有個公園,面積不算大染厅,綠化卻搞得極好痘绎。 我是個懶人,如果有電梯可坐肖粮,上個二樓孤页,我也是不愿意爬...
    一之魚閱讀 271評論 0 0
  • (一) 今天是放假第一天,恰好是族長生日涩馆,周作業(yè)就是行施,跑步三十分鐘給她慶祝生日嘍。 我從九點多魂那,開始慢跑加快走蛾号,大...
    月朦朧0鳥朦朧閱讀 125評論 2 2
  • 在線批注功能是巴別鳥的一大特色之一斩芭,作為一個協(xié)作網(wǎng)盤轻腺,在線批注功能可以讓協(xié)作多方基于文件內(nèi)容精確討論,使溝通內(nèi)容清...
    深海淡藍閱讀 2,019評論 0 0
  • 今天很榮幸的被選派去觀摩全國特級教師吳正憲老師以及泉州師范學(xué)院副教授蘇清明兩位老師的實際授課課堂划乖。兩位老師以獨具個...
    Karuna哈哈兔閱讀 1,081評論 0 1