姓名:劉成龍 ?學號:16020199016
轉載自:https://www.jiqizhixin.com/articles/2018-10-01-5,有刪節。
【嵌牛導讀】:一圖抵千言:帶你了解最直觀的神經網絡架構可視化
【嵌牛鼻子】:可視化整個神經網絡架構和特定模塊的工具和技巧
【嵌牛提問】:如何在避免過于復雜或重復的情況下呈現深度學習模型架構的重要特征呢?
【嵌牛正文】:
神經網絡是復雜、多維、非線性的數組運算。如何在避免過于復雜或重復的情況下呈現深度學習模型架構的重要特征呢?又該以何種方式清晰直觀、啟發性地呈現它們呢?(好看也是加分項!)無論研究還是教學項目對此都沒有固定標準。本文我們就來了解一下可視化整個神經網絡架構和特定模塊的工具和技巧。
基線
AlexNet?是突破性的架構,它使卷積網絡(CNN)成為處理大型圖像分類任務的主要機器學習算法。介紹?AlexNet?的論文呈現了一張很好的圖,但是好像還缺點什么……
AlexNet?架構圖示。(圖源:《ImageNet?Classification?with Deep Convolutional?Neural Networks》http://www.cs.toronto.edu/~fritz/absps/imagenet.pdf)
不需費力也能看出這張圖的上半部分被意外裁掉了,而這張圖會貫穿后續所有的幻燈片、參考文獻等。在我看來,這說明在深度學習的研究中,可視化并不受重視(當然也有一些例外,比如線上期刊 Distill)。
有人會辯解:開發新算法和調參是真正的科學/工程,但視覺呈現則屬于藝術領域,且毫無價值。我完全不同意這種觀點!
當然,對于運行程序的計算機而言,代碼沒有縮進或者變量命名比較模糊可能無傷大雅。但對人類則不然。學術論文不是一種發現方式,而是交流方式。
以另一個復雜的理論——量子場論為例。如果你想要呈現電子-正電子的湮沒過程,就要創建一個 μ 子-反 μ 子對,下圖是費曼圖(一階項):
圖源:https://www.hep.phy.cam.ac.uk/~thomson/partIIIparticles/handouts/Handout_4_2011.pdf
這很可愛對吧?但這張圖沒有什么藝術性可言。它只是散射振幅的圖形表示,這張圖中的每條線都是一個傳播子,每一個頂點都表示點和點的交互。這張圖可以直接變成下式:
我可能更偏向于「使事情更簡單」,就像我在 JavaScript 中處理復雜張量運算一樣,而且提前可視化結果是一件很酷的事情。在量子力學和深度學習中,我們都可以用張量結構做大量線性代數的運算。事實上,甚至有人用 Pytorch 實現愛因斯坦求和約定。
解釋神經網絡的層
在了解網絡架構之前,我們先來關注一下網絡的基本構建模塊——層。例如,可以用下式描述長短期記憶模型(LSTM)單元:
當然,如果你對矩陣乘法熟悉的話,可以很容易地解出這些等式。但解出這些等式是一回事,理解它們就是另一回事了。我第一次看到?LSTM?的公式時就可以解出來,但我不知道它們是什么意思。
我所說的「理解」不是指精神上的啟蒙,而是建立一個我們能夠使用的心理模型(用于解釋、簡化、修改和預測 what-if 情景等)。一般而言,圖表會比口頭說明更清晰:
圖源:http://colah.github.io/posts/2015-08-Understanding-LSTMs/
《理解?LSTM?網絡》是一篇關于?LSTM?的好文章,這篇文章一步步解釋了?LSTM?的原理。這篇文章使我靈光一現,將一組看似隨機的乘法集合轉換為寫作(閱讀)數據的合理方法。
下圖是一個更清晰的?LSTM?圖:
圖源:https://eli.thegreenplace.net/2018/minimal-character-based-lstm-implementation/
我認為:一張好的圖抵得上一千個公式。
這幾乎適用于任何模塊。我們可以將概念可視化,如 dropout:
圖源:論文《Dropout: A Simple Way to Prevent?Neural Networks from?Overfitting》(http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf)
圖示可用于解釋由更小的模塊(例如幾個后面的卷積)組成的復合模塊。看一下這個 Inception 模塊的圖:
圖源:論文《Rethinking the Inception Architecture for?Computer Vision》(https://arxiv.org/abs/1512.00567)
每個可視化的圖像都是不同的——不僅是風格不同,它強調的重點和抽象的內容也不同。那么哪些是重要的呢?層數、層與層之間的連接、卷積核大小還是激活函數?這都要視情況而定。抽象意味著「獨立思考事物聯系和屬性的過程」。難點在于確定哪些要重點強調,以及哪些可以簡要概括。
例如,在批歸一化(Batch?Normalization)的圖中,重點是逆推過程:
圖源:https://kratzert.github.io/2016/02/12/understanding-the-gradient-flow-through-the-batch-normalization-layer.html
數據可視化與數據藝術
你可能覺得我是想讓深度學習的文章看起來更具吸引力。可是讓圖表更好看也沒什么壞處啊。當我在進行數據探索時,我一般會用好看的配色方案,以使讀者獲得更好的閱讀體驗。我的主要觀點是將可視化圖像轉變為更高效的溝通手段。
所以,更好看就意味更好嗎?不一定。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/Sinapsis/
要明確的是:只要我們不混淆藝術價值和教育價值,則數據藝術自身就有價值。如果你喜歡我的觀點,那么我鼓勵你用像火花或五顏六色的大腦這樣的 3D 動畫可視化真正的卷積網絡。
有時候這種取舍也沒那么明確。像下面這張圖,它體現的是數據的可視化還是數據的藝術?
圖源:論文《Going Deeper with Convolutions》(https://arxiv.org/abs/1409.4842Christian)
我猜你肯定會說:「這顯然是數據可視化」。就本例而言,我們的意見出現了分歧。雖然這張圖的配色方案很好,而且相似結構的重復看起來很愉快,但要根據這張圖實現這個網絡還是有難度的。當然,你能得到這個網絡架構的重點——即層的數量以及模塊的結構,但是要想重現該網絡只有這些還不夠(至少在沒有放大鏡的情況下是無法實現這個網絡的)。
為了讓圖像變得清楚,出版物一般會為數據藝術留有一定的空間。例如,在一個用于檢測皮膚狀態的網絡中,我們可以看到 Inception v3 特征提取層的圖。很明顯,作者只是使用該模型并用圖表示了出來,而沒有解釋其內部工作原理:
圖源:https://cs.stanford.edu/people/esteva/nature/
為了研究激活所選通道的視覺模式,你要如何對下面的兩幅圖進行分類?
圖源:https://distill.pub/2017/feature-visualization/appendix/
我會把下方的圖作為數據可視化的很好示例。迷幻的圖像不意味著就是數據藝術。這個例子的重點在于網絡架構抽象化以及相關數據的呈現(激活給定通道的輸入圖像)。
解釋性架構圖
我們看了一些層圖示的例子,以及與神經網絡架構相關的數據藝術。
下面就來了解一下神經網絡架構的(數據)可視化。下圖是 VGG16 的架構,VGG 16 是用于圖像分類的標準網絡。
圖源:https://blog.heuritech.com/2016/02/29/a-brief-report-of-the-heuritech-deep-learning-meetup-5/
我們可以看到每一步的張量大小以及操作(用顏色標記)。它不是抽象的——盒子大小與張量形狀相關。但厚度和通道數量并不成比例。
還有類似的方式是顯示每個通道的值,如 DeepFace 工作示例圖:?
圖源:https://research.fb.com/publications/deepface-closing-the-gap-to-human-level-performance-in-face-verification/
這樣的圖不僅限于計算機視覺。下面是一個將文本轉換為顏色的例子:
圖源: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.03385)
我們可以看出,上圖存在一些冗余,因為有一些重復使用的單元。由于圖像可能很長,最好是找到其模式并對其進行合并。這樣的層級結構使理解概念以及從視覺角度呈現它們變得更加簡單(除非我們只想創建 GoogLeNet 的數據藝術圖)。
舉個例子,我們看一下 Inception-ResNet-v1 的圖:
圖源:論文《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》(https://arxiv.org/abs/1602.07261)
我喜歡這個圖的構成——我們可以看到發生了什么以及重復使用了哪些模塊。
另一個讓我對概念更加明晰的圖是用于圖像分割的 U-Net 的圖:
圖源:https://lmb.informatik.uni-freiburg.de/people/ronneber/u-net/
注意,這里的節點表示張量,箭頭表示操作。我發現這張圖非常清楚——我們可以看到張量的形狀、卷積操作以及池化操作。因為原始的 U-Net 架構不是很復雜,因此我們可以不看它的層級結構。
當我們想用更復雜的構造塊創建清晰的圖的話會稍微復雜一點。如果要重現網絡,我們需要了解網絡的細節:
通道的數量;
每個最大池化中的卷積;
最大池化的數量;
批歸一化或 dropout;
激活函數(是不是用 ReLu 函數?是在 BN 之前還是之后?)
下面就是一個很好的抽象圖示例:
圖源:https://deepsense.ai/deep-learning-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/files/2018-TensorFlowGraph-VAST.pdf)
這篇文章提供了一些有關從下而上創建網絡圖所遇到的挑戰的見解。雖然我們可以使用所有?TensorFlow 的操作,包括輔助操作(例如初始化工具以及日志工具),但做出一張通用的、可讀的圖依舊是個挑戰。如果讀者重視的東西我們卻不重視,那就沒法做出將?TensorFlow 計算圖轉變為有用的(比如發布就緒)圖的通用工具。
Keras
Keras 是一個高級深度學習框架,因此它具有生成美觀的可視化圖的巨大潛力。(注:如果你想使用用于 Jupyter Notebook 的交互訓練圖,我寫了一個:livelossplot(https://github.com/stared/livelossplot)。)然而在我看來,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/questions/1057564/pretty-git-branch-graphs))。顯而易見,我不是唯一一個試著用 ASCII 美化神經網絡可視化圖的人:
圖源:https://github.com/brianlow/keras_diagram
我認為最美觀的圖是我在 Keras.js 中找到的:
圖源:https://transcranial.github.io/keras-js/#/squeezenet-v1.1
該項目沒有處于積極開發狀態,但它支持?TensorFlow.js。由于它是開源且模塊化的(用了 Vue.js 框架),它可以作為創建獨立的可視化項目的起點。在理想情況下,用 Jupyter Notebook 或單獨的瀏覽器窗口工作,就像用 displaCy 分解句子一樣。
總結
我們看了許多神經網絡可視化的例子,這些例子都在以下方面做了取舍:
數據可視化 vs 數據藝術(有用性和美觀性)
清晰 vs 模糊
淺層 vs 層級
靜態(在出版物中效果很好)vs 交互(提供了更多信息)
特定 vs 通用(它是否適用于廣泛的神經網絡族?)
數據流方向(從上到下、從下到上還是從左到右?)
這些主題中的每一個都可以寫一篇碩士論文,而將所有的合并在一起就可以寫一篇博士論文(尤其是對人們如何進行可視化以及應該將哪些內容抽象進行細致的研究)。