一張好的圖抵得上一千個等式。
神經網路是複雜、多維、非線性的陣列運算。如何在避免過於複雜或重複的情況下呈現深度學習模型架構的重要特徵呢?又該以何種方式清晰直觀、啟發性地呈現它們呢?(好看也是加分項!)無論研究還是教學專案對此都沒有固定標準。本文我們就來了解一下視覺化整個神經網路架構和特定模組的工具和技巧。
基線
AlexNet 是突破性的架構,它使卷積網路(CNN)成為處理大型影象分類任務的主要機器學習演算法。介紹 AlexNet 的論文呈現了一張很好的圖,但是好像還缺點什麼……
AlexNet 架構圖示。(圖源:《ImageNet Classification with Deep Convolutional Neural Networks》 http://www. cs.toronto.edu/~fritz/a bsps/imagenet.pdf )
不需費力也能看出這張圖的上半部分被意外裁掉了,而這張圖會貫穿後續所有的幻燈片、參考文獻等。在我看來,這說明在深度學習的研究中,視覺化並不受重視(當然也有一些例外,比如線上期刊 Distill)。
有人會辯解:開發新演算法和調參是真正的科學/工程,但視覺呈現則屬於藝術領域,且毫無價值。我完全不同意這種觀點!
當然,對於執行程式的計算機而言,程式碼沒有縮排或者變數命名比較模糊可能無傷大雅。但對人類則不然。學術論文不是一種發現方式,而是交流方式。
以另一個複雜的理論——量子場論為例。如果你想要呈現電子-正電子的湮沒過程,就要建立一個 μ 子-反 μ 子對,下圖是費曼圖(一階項):
圖源: https://www. hep.phy.cam.ac.uk/~thom son/partIIIparticles/handouts/Handout_4_2011.pdf
這很可愛對吧?但這張圖沒有什麼藝術性可言。它只是散射振幅的圖形表示,這張圖中的每條線都是一個傳播子,每一個頂點都表示點和點的互動。這張圖可以直接變成下式:
我可能更偏向於「使事情更簡單」,就像我在 JavaScript 中處理複雜張量運算一樣,而且提前視覺化結果是一件很酷的事情。在量子力學和深度學習中,我們都可以用張量結構做大量線性代數的運算。事實上,甚至有人用 Pytorch 實現愛因斯坦求和約定。
解釋神經網路的層
在瞭解網路架構之前,我們先來關注一下網路的基本構建模組——層。例如,可以用下式描述長短期記憶模型(LSTM)單元:
當然,如果你對矩陣乘法熟悉的話,可以很容易地解出這些等式。但解出這些等式是一回事,理解它們就是另一回事了。我第一次看到 LSTM 的公式時就可以解出來,但我不知道它們是什麼意思。
我所說的「理解」不是指精神上的啟蒙,而是建立一個我們能夠使用的心理模型(用於解釋、簡化、修改和預測 what-if 情景等)。一般而言,圖表會比口頭說明更清晰:
圖源: http:// colah.github.io/posts/2 015-08-Understanding-LSTMs/
《理解 LSTM 網路》是一篇關於 LSTM 的好文章,這篇文章一步步解釋了 LSTM 的原理。這篇文章使我靈光一現,將一組看似隨機的乘法集合轉換為寫作(閱讀)資料的合理方法。
下圖是一個更清晰的 LSTM 圖:
圖源: https:// eli.thegreenplace.net/2 018/minimal-character-based-lstm-implementation/
我認為:一張好的圖抵得上一千個公式。
這幾乎適用於任何模組。我們可以將概念視覺化,如 dropout:
圖源:論文《Dropout: A Simple Way to Prevent Neural Networks from Overfitting》( http://www. cs.toronto.edu/~rsalakh u/papers/srivastava14a.pdf )
圖示可用於解釋由更小的模組(例如幾個後面的卷積)組成的複合模組。看一下這個 Inception 模組的圖:
圖源:論文《Rethinking the Inception Architecture for Computer Vision》( https:// arxiv.org/abs/1512.0056 7 )
每個視覺化的影象都是不同的——不僅是風格不同,它強調的重點和抽象的內容也不同。那麼哪些是重要的呢?層數、層與層之間的連線、卷積核大小還是啟用函式?這都要視情況而定。抽象意味著「獨立思考事物聯絡和屬性的過程」。難點在於確定哪些要重點強調,以及哪些可以簡要概括。
例如,在批歸一化(Batch Normalization)的圖中,重點是逆推過程:
資料視覺化與資料藝術
你可能覺得我是想讓深度學習的文章看起來更具吸引力。可是讓圖表更好看也沒什麼壞處啊。當我在進行資料探索時,我一般會用好看的配色方案,以使讀者獲得更好的閱讀體驗。我的主要觀點是將視覺化影象轉變為更高效的溝通手段。
所以,更好看就意味更好嗎?不一定。Lisa Charlotte Rost 的文章《The Line between Data Vis and Data Art》就很有見地地解釋了二者之間的區別。
圖源: https:// lisacharlotterost.github.io /2015/12/19/Meaning-and-Beauty-in-Data-Vis/
以下圖為例:
圖源: https://www. graphcore.ai/posts/what -does-machine-learning-look-like
很美吧。對我來說,它看起來就像是有生命的——像是一個帶有細胞器的細胞。但是我們能從中推斷出什麼嗎?你猜得到它其實就是 AlexNet 嗎?
舉另一個例子,這是一個更注重美學而非其解釋價值的多層感知器動圖圖示:
圖源: http:// chumo.github.io/Sinapsi s/
要明確的是:只要我們不混淆藝術價值和教育價值,則資料藝術自身就有價值。如果你喜歡我的觀點,那麼我鼓勵你用像火花或五顏六色的大腦這樣的 3D 動畫視覺化真正的卷積網路。
有時候這種取捨也沒那麼明確。像下面這張圖,它體現的是資料的視覺化還是資料的藝術?
圖源:論文《Going Deeper with Convolutions》( https:// arxiv.org/abs/1409.4842 Christian )
我猜你肯定會說:「這顯然是資料視覺化」。就本例而言,我們的意見出現了分歧。雖然這張圖的配色方案很好,而且相似結構的重複看起來很愉快,但要根據這張圖實現這個網路還是有難度的。當然,你能得到這個網路架構的重點——即層的數量以及模組的結構,但是要想重現該網路只有這些還不夠(至少在沒有放大鏡的情況下是無法實現這個網路的)。
為了讓影象變得清楚,出版物一般會為資料藝術留有一定的空間。例如,在一個用於檢測皮膚狀態的網路中,我們可以看到 Inception v3 特徵提取層的圖。很明顯,作者只是使用該模型並用圖表示了出來,而沒有解釋其內部工作原理:
圖源: https:// cs.stanford.edu/people/ esteva/nature/
為了研究啟用所選通道的視覺模式,你要如何對下面的兩幅圖進行分類?
圖源: https:// distill.pub/2017/featur e-visualization/appendix/
我會把下方的圖作為資料視覺化的很好示例。迷幻的影象不意味著就是資料藝術。這個例子的重點在於網路架構抽象化以及相關資料的呈現(啟用給定通道的輸入影象)。
解釋性架構圖
我們看了一些層圖示的例子,以及與神經網路架構相關的資料藝術。
下面就來了解一下神經網路架構的(資料)視覺化。下圖是 VGG16 的架構,VGG 16 是用於影象分類的標準網路。
圖源: https:// blog.heuritech.com/2016 /02/29/a-brief-report-of-the-heuritech-deep-learning-meetup-5/
我們可以看到每一步的張量大小以及操作(用顏色標記)。它不是抽象的——盒子大小與張量形狀相關。但厚度和通道數量並不成比例。
還有類似的方式是顯示每個通道的值,如 DeepFace 工作示例圖:
這樣的圖不僅限於計算機視覺。下面是一個將文字轉換為顏色的例子:
圖源: https:// heartbeat.fritz.ai/how- to-train-a-keras-model-to-generate-colors-3bc79e54971b
如果目的是呈現網路架構同時說明內部工作原理的話,這樣的圖就顯得非常有用了。在教程中它們似乎尤其有用,例如 http:// karpathy.github.io/2015 /05/21/rnn-effectiveness/ 。
抽象的架構圖
但對大型模型而言,解釋性的圖可能太過複雜或太過具體,以至於它們無法在一個圖內呈現所有可能的層。所以就要用抽象圖。一般而言,節點表示運算,箭頭表示張量流。比較 VGG-19 和 ResNet-34:
圖源:論文《Deep Residual Learning for Image Recognition》( https:// arxiv.org/abs/1512.0338 5 )
我們可以看出,上圖存在一些冗餘,因為有一些重複使用的單元。由於影象可能很長,最好是找到其模式並對其進行合併。這樣的層級結構使理解概念以及從視覺角度呈現它們變得更加簡單(除非我們只想建立 GoogLeNet 的資料藝術圖)。
舉個例子,我們看一下 Inception-ResNet-v1 的圖:
圖源:論文《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》( https:// arxiv.org/abs/1602.0726 1 )
我喜歡這個圖的構成——我們可以看到發生了什麼以及重複使用了哪些模組。
另一個讓我對概念更加明晰的圖是用於影象分割的 U-Net 的圖:
圖源: https:// lmb.informatik.uni-freiburg.de /people/ronneber/u-net/
注意,這裡的節點表示張量,箭頭表示操作。我發現這張圖非常清楚——我們可以看到張量的形狀、卷積操作以及池化操作。因為原始的 U-Net 架構不是很複雜,因此我們可以不看它的層級結構。
當我們想用更復雜的構造塊建立清晰的圖的話會稍微複雜一點。如果要重現網路,我們需要了解網路的細節:
通道的數量;
每個最大池化中的卷積;
最大池化的數量;
批歸一化或 dropout;
啟用函式(是不是用 ReLu 函式?是在 BN 之前還是之後?)
下面就是一個很好的抽象圖示例:
圖源: https:// deepsense.ai/deep-learn ing-for-satellite-imagery-via-image-segmentation/ )
這張圖在配色方面還可以做得更好,不過我喜歡它簡潔的形式。圖中還清晰地說明了通道數量,將每一個複雜的層清晰地分解為其構造塊,保留了所有的細節(注意 3 級層級結構)。
還有一個表示神經網路模組層次的有趣方法:
圖源: http:// deepscene.cs.uni-freiburg.de /
神經網路架構視覺化的自動化工具
你可以手動繪製網路。像 Chris Olah 那樣用 Inkscape、如果你喜歡 LaTeX 的話可以用 TikZ,也可以用其他工具。你也可以自動生成影象。
我希望你能意識到你已經在用視覺表示——程式碼(文字就是一種視覺表示!)——來與計算機進行互動。對某些專案而言,程式碼就足夠了,尤其是如果你用的是簡潔的框架(如 Keras 或 PyTorch)。對更復雜的架構來說,圖會增加一些解釋性的價值。
TensorBoard:圖
TensorBoard 可以說是最常用的網路視覺化工具。下圖所示是一個 TensorFlow 網路圖:
這張圖是否提供了可讀性較高的神經網路的概述?
我認為沒有。
雖然這張圖呈現了計算結構,但還是有些囉嗦(比如將偏置項作為單獨的操作新增進去)。此外,它掩蓋了網路最重要的部分:操作中的核心引數(如卷積核的大小)以及張量的大小。儘管有這麼多的不足,我還是推薦大家閱讀完整的論文:
Visualizing Dataflow Graphs of Deep Learning Models in TensorFlow( http:// idl.cs.washington.edu/f iles/2018-TensorFlowGraph-VAST.pdf )
這篇文章提供了一些有關從下而上建立網路圖所遇到的挑戰的見解。雖然我們可以使用所有 TensorFlow 的操作,包括輔助操作(例如初始化工具以及日誌工具),但做出一張通用的、可讀的圖依舊是個挑戰。如果讀者重視的東西我們卻不重視,那就沒法做出將 TensorFlow 計算圖轉變為有用的(比如釋出就緒)圖的通用工具。
Keras
Keras 是一個高階深度學習框架,因此它具有生成美觀的視覺化圖的巨大潛力。(注:如果你想使用用於 Jupyter Notebook 的互動訓練圖,我寫了一個:livelossplot( https:// github.com/stared/livel ossplot )。)然而在我看來,Keras 的預設視覺化選項(使用 GraphViz)並非一流:
圖源: https:// keras.io/visualization/
我認為它不僅隱藏了重要的細節,還提供了冗餘的資料(重複的張量大小)。從美學上講,我也不喜歡它。
我試著寫了另一個(pip install keras_sequential_ascii)用於訓練:
圖源: https:// github.com/stared/keras -sequential-ascii (2017)
這個結構適用於小型序列網路架構。我發現它對訓練和「Starting deep learning hands-on: image classification on CIFAR-10」這樣的課程很有用。但對更高階的專案則毫無用武之地(有人建議我用這篇 git 日誌中的分支視覺化工具( https:// stackoverflow.com/quest ions/1057564/pretty-git-branch-graph s))。顯而易見,我不是唯一一個試著用 ASCII 美化神經網路視覺化圖的人:
圖源: https:// github.com/brianlow/ker as_diagram
我認為最美觀的圖是我在 Keras.js 中找到的:
圖源: https:// transcranial.github.io/ keras-js/#/squeezenet-v1.1
該專案沒有處於積極開發狀態,但它支援 TensorFlow.js。由於它是開源且模組化的(用了 Vue.js 框架),它可以作為建立獨立的視覺化專案的起點。在理想情況下,用 Jupyter Notebook 或單獨的瀏覽器視窗工作,就像用 displaCy 分解句子一樣。
總結
我們看了許多神經網路視覺化的例子,這些例子都在以下方面做了取捨:
資料視覺化 vs 資料藝術(有用性和美觀性)
清晰 vs 模糊
淺層 vs 層級
靜態(在出版物中效果很好)vs 互動(提供了更多資訊)
特定 vs 通用(它是否適用於廣泛的神經網路族?)
資料流方向(從上到下、從下到上還是從左到右?)