轉載地址:https://zhuanlan.zhihu.com/p/24833574
一.前言
CNN作為一個著名的深度學習領域的“黑盒”模型,已經在計算機視覺的諸多領域取得了極大的成功,但是,至今沒有人能夠“打開”這個“黑盒”,從數學原理上予以解釋。這對理論研究者,尤其是數學家來說當然是不可接受的,但換一個角度來說,我們終於創造出了無法完全解釋的事物,這也未嘗不是一種進步了!
當然,雖然無法完全“打開”這個“黑盒”,但是仍然出現了很多探索這個“黑盒”的嘗試工作。其中一個工作就是今天我們討論的重點:可視化CNN模型,這里的可視化指的是可視化CNN模型中的卷積核。
可視化工作分為兩大類,一類是非參數化方法:這種方法不分析卷積核具體的參數,而是先選取圖片庫,然后將圖片在已有模型中進行一次前向傳播,對某個卷積核,我們使用對其響應最大的圖片塊來對之可視化;而另一類方法着重分析卷積核中的參數,使用參數重構出圖像。
這一篇文章着重分析第一類可視化方法。
二.發展
最初的可視化工作見於AlexNet[1]論文中。在這篇開創Deep Learning新紀元的論文中,Krizhevshy直接可視化了第一個卷積層的卷積核:
我們知道,AlexNet[1]首層卷積層(conv1)的filters是(96,3,11,11)的四維blob,這樣我們就可以得到上述96個11*11的圖片塊了。顯然,這些重構出來的圖像基本都是關於邊緣,條紋以及顏色的信息。但是這種簡單的方法卻只適用於第一層卷積層,對於后面的卷積核我們就無法使用這種方法進行直接可視化了。
最開始使用圖片塊來可視化卷積核是在RCNN[2]論文中,

Girshick[2]的工作顯示了數據庫中對AlexNet模型較高層(pool5)某個channel具有較強響應的圖片塊;
之后,在ZFNet[4]論文中,系統化地對AlexNet進行了可視化,並根據可視化結果改進了AlexNet得到了ZFNet,拿到了ILSVRC2014的冠軍。這篇文章可以視為CNN可視化的真正開山之作,我們下面將重點分析一下這一篇:[1311.2901] Visualizing and Understanding Convolutional Networks
然后再2015年,Yosinski[5]根據以往的可視化成果(包括參數化和非參數化方法)開發了一個可用於可視化任意CNN模型的toolbox:yosinski/deep-visualization-toolbox,通過簡單的配置安裝之后,我們就可以對CNN模型進行可視化了。
三.論文解讀
Abstract
CNN模型已經取得了非常好的效果,但是正如前面所言,CNN在大多數人眼中,只是一個“黑盒”模型,它為什么表現得這么好,以及如何提升CNN的精度,這些都是不清楚的。這篇文章研究了這些問題。文中介紹了一種新的可視化方法,借助它,我們可以深入了解中間層和分類器的功能。通過使用類似診斷的方式,作者還得到了比AlexNet更好的結構:ZFNet;最后,作者還通過在ImageNet上訓練,然后在其他數據集上進行fine-tuning,得到了非常好的結果。
1.Introduction
CNN在圖像分類和物體檢測領域大放異彩,主要是以下幾項因素的作用:1).數以百萬計帶標簽的訓練數據的出現;2).GPU的強大計算能力,使得訓練大的模型成為可能。
盡管如此,從科學的角度來看,這是令人很不滿意的。因為我們並不能解釋這個復雜的模型,也就不理解為什么它能達到這么好的效果,而不了解這個模型如何工作和為什么有作用,我們改進模型就只能使用試錯法。這篇論文提出了一種新的可視化技術,揭示了模型中任意層的feature map與輸入之間的響應關系。
2.Approach
2.1 Visualization with a Deconvnet
為了了解卷積操作,我們需要首先了解中間層的特征激活值。我們使用了一種新的方式將這些激活值映射回輸入像素空間,表明了什么樣的輸入模式將會導致feature map中一個給定的激活值。我們使用反卷積網絡來完成映射[6]。一個反卷積網絡可以被看成是一個卷積模型,這個模型使用和卷積同樣的組件(過濾和池化),但是卻是相反的過程,因此是將特征映射到像素。在[6]中,反卷積網絡被提出作為一種進行非監督學習的方法,但是在這里,它沒有學習能力,僅僅用來探測一個已經訓練好的卷積神經網絡。

如上圖所示,反卷積可視化以各層得到的特征圖作為輸入,進行反卷積,得到結果,用以驗證顯示各層提取到的特征圖。為檢驗一個給定CNN的激活,我們就將該激活的feature map后接一個反卷積網絡,然后通過:反池化、反激活、反卷積。重復上述過程直到原始輸入層。
Unpooling:
在卷積神經網絡中,max-pooling操作是不可逆的,然而我們可以通過一系列switch變量來記錄池化過程中最大激活值的坐標位置。在反池化的時候,只把池化過程中最大激活值所在的位置坐標的值激活,其它的值置為0,當然這個過程只是一種近似,因為我們在池化的過程中,除了最大值所在的位置,其它的值也是不為0的。過程如下圖所示:
Rectification:
CNN使用ReLU確保每層輸出的激活之都是正數,因此對於反向過程,我們同樣需要保證每層的特征圖為正值,也就是說這個反激活過程和激活過程沒有什么差別,都是直接采用relu函數。
Filtering:
卷積過程使用學習到的過濾器對feature map進行卷積,為近似反轉這個過程,反卷積使用該卷積核的轉置來進行卷積操作
注意在上述重構過程中我們沒有使用任何對比度歸一化操作
3.Training Details
略
4.Convnet Visualization
使用前面描述的方法,現在我們使用在ImageNet驗證集上使用反卷積進行特征圖的可視化.
1.Feature Visualization:



以上就是對模型的可視化結果。對於一個給定的feature map,我們展示了響應最大的九張響應圖,每個響應圖向下映射到像素空間,揭示出其不同的結構激發映射並且揭示出其對輸入變形的不變性。在這些可視化結果邊上我們展示了對應的圖片塊。這些具有比僅僅關注圖片塊中判別結構的可視化具有更大的變化。例如,在layer5的第一行第二列,這些圖片塊似乎沒有什么共同之處,但是從左邊的可視化結果我們可以看出,這個特殊的feature map關注的是背景中的草,而不是前景中的物體。
來自每個層中的投影顯示出網絡中特征的分層特性。第二層響應角落和其他的邊緣/顏色信息,層三具有更復雜的不變性,捕獲相似的紋理,層四顯示了顯著的變化,並且更加類別具體化,層五則顯示了具有顯著姿態變化的整個對象。
---------------------------------------------------------------------------------------------------------------------------
這里的內容是這篇文章極其重要的貢獻,雖然還是不能完全解釋CNN這個黑盒,但是通過可視化,我們發現了CNN學習到的特征呈現分層特性,底層是一些邊緣角點以及顏色的抽象特征,越到高層則越呈現出具體的特征,這一過程正與人類視覺系統類似。這也為如何得到更好的模型給出了指導,一個最簡單的思路便是使網絡更深,使得每層的特征更加層次分明,這樣就能學到更加泛化的特征,后來的VGGNet以及ResNet則證明了這一點。上圖中左側的圖像就是根據反卷積網絡得到的結果,下面我們詳細解釋一下右側的圖片塊是如何得到的。
首先我們介紹一下感受野(Receptive Field)[7]:
感受野是一個非常重要的概念,receptive field往往是描述兩個feature maps A/B上神經元的關系,假設從A經過若干個操作得到B,這時候B上的一個區域
只會跟a上的一個區域
相關,這時候
成為
的感受野。用圖片來表示:
在上圖里面,map3里1x1的區域對應map2的receptive field是那個紅色的7x7的區域,而map2里7x7的區域對應於map1的receptive field是藍色的11x11的區域,所以map3里1x1的區域對應map 1的receptive field是藍色的11x11的區域。
那么很容易得出來,receptive field的計算公式如下:
- 對於Convolution/Pooling layer:
 

其中
表示第i層layer的輸入的某個區域,
表示第i層layer的步長,
表示kernel size,注意,不需要考慮padding size。
- 對於Neuron layer(ReLU/Sigmoid/…)
 
 
很容易看出,除了不考慮padding之外,上述過程與反卷積計算feature map的尺寸的公式是一樣的。
而上述計算圖片塊的過程正是應用了感知野的概念,我們舉個例子:
首先圖片經過AlexNet做一次前向傳播,之后在conv5層可以得到一個feature map,我們對這個feature map做一次max pooling,只保留其中響應最大的值(1x1),然后根據以上感受野的計算公式一路計算回輸入圖像中:
AlexNet結構如下:
其中ReLU和LRN層感受野不會產生變化,所以我們只需要考慮pool層和conv層:
conv5: 
conv4: 
conv3: 
pool2: 
conv2: 
pool1: 
conv1: 
所以,conv5層一個feature map中響應最大的值所對應的輸入圖中的感受野是163x163的尺寸,我們從原圖中切割出163x163的圖片塊即可。這就是論文中圖片塊的來源。
---------------------------------------------------------------------------------------------------------------------------
2.Feature Evolution during Training:
上圖顯示了訓練過程中的特征演變,對於一個layer中給定的feature map,圖中給出在訓練epochs在[1,2,5,10,20,30,40,64]時,訓練集對該feature map響應最大的可視化圖片。可以看出,較低層(L1,L2)只需要幾個epochs就可以完全收斂,而高層(L5)則需要很多次迭代,需要讓模型完全收斂之后。這一點正好與深層網絡的梯度彌散現象正好相反,但是這種底層先收斂,然后高層再收斂的現象也很符合直觀
3.Feature Invariance:
 
上圖顯示出了相對於未變換的特征,通過垂直平移,旋轉和縮放的5個樣本圖像在可視化過程中的變化。小變換對模型的第一層有着顯著的影響,但對頂層影響較小,對於平移和縮放是准線性的。網絡輸出對於平移和縮放是穩定的。但是一般來說,除了具有旋轉對稱性的物體來說,輸出來旋轉來說是不穩定的.(這說明了卷積操作對於平移和縮放具有很好的不變性,而對於旋轉的不變性較差)
4.1 Architecture Selection
 
可視化訓練模型不但可以洞察CNN的操作,也可以幫助我們在前幾層選擇更好的模型架構。通過可視化AlexNet的前兩層(圖中b,d),我們就可以看出問題:
1)第一層filter是非常高頻和低頻的信息,中間頻率的filter很少覆蓋
2)第二層的可視化有些具有混疊效應,由於第一層比較大的stride
為了解決這些問題:
1)將第一層的filter的尺寸從11*11減到7*7
2)縮小間隔,從4變為2。
這兩個改動形成的新結構,獲取了更多的信息,而且提升了分類准確率。
4.2 Occlusion Sensitivity
 
對於圖片分類方法,一個自然的問題就是模型究竟是真正確定物體在圖片中的位置,或者只是使用了周圍的上下文信息,上圖嘗試通過使用一個灰色方形系統地遮擋輸入圖中的不同部分來回答這個問題,並監視分類器的輸出。示例清楚地表明,模型是在場景中定位物體,因為當物體被遮擋住時被正確識別的概率顯著下降了。
4.3 Correspondence Analysis
深度模型與許多現有的識別方法的區別在於,它沒有用於建立不同圖像中的特定對象部分之間的顯式機制。然而,一個有趣的可能性是,深層模型可能隱式地計算它們。
 

為了驗證這一點,我們隨機選擇了5張包含狗正臉的圖片;然后遮蔽相同的部分來觀察。
觀察方法:首先計算圖片遮蔽前后特征,兩個特征向量做差,通過sign來確定符號;然后通過海明距離來計算5張照片兩兩之間的一致性,然后求和。
由實驗結果可以得出,layer5的特征一致性中,眼和鼻子的數值較低,說明眼和鼻子比其他部分,有更強的相關性,這也說明深度網絡能夠隱式地建立對應關系。但是在layer7中眼,鼻子和隨機的數值較為相似,可能是因為高層嘗試去區分狗的種類。
5 Experiments
略
四.可視化實踐
論文終於解讀完了,上述論文是Deep Learning發展中一篇很重要的論文,因為他嘗試從可視化的角度去解釋CNNs中的機制,通過各種實驗也確實發現了很多有趣而重要的結論,如CNN中特征學習的分層性質,訓練過程中的特征演變,CNN對於平移和縮放的不變性。
接下來我們使用[5]中的Deep Visualization toolbox對CNN進行可視化。
知乎專欄 首先我們按照這篇文章在VirtualBox Ubuntu14.04中安裝配置好caffe,
1.Compile the deconv-deep-vis-toolbox branch of caffe
$ git remote add yosinski https://github.com/yosinski/caffe.git
$ git fetch --all
$ git checkout --track -b deconv-deep-vis-toolbox yosinski/deconv-deep-vis-toolbox
$ make clean
$ make -j
$ make -j pycaffe
 
        2.Install prerequisites
$ sudo apt-get install python-opencv scipy python-skimage
 
        3.Download and configure Deep Visualization Toolbox code
$ git clone https://github.com/yosinski/deep-visualization-toolbox
$ cd deep-visualization-toolbox  
        $ cp models/caffenet-yos/settings_local.template-caffenet-yos.py settings_local.py
 
        然后我們修改settings_local.py中的caffe路徑,改成我們的安裝路徑即可
$ vim settings_local.py
 
        $ cd models/caffenet-yos/ $ ./fetch.sh $ cd ../..  
        4.Run it
$ ./run_toolbox.py
 
        不出意外的外,應該會出現這樣的toolbox:
左上角是輸入圖片,中間的部分是對圖片經過網絡(這里是CaffeNet)進行前向傳播之后得到feature map的可視化,我們可以通過上下左右控制光標移動,按'h'鍵可以查看按鍵的功能,我們嘗試移動一下光標,看一下conv5的第151個feature map,
左邊的中間區域是feature map的放大版本,右側上方的九張圖片是參數化的可視化方法(gradient ascent),這里暫且不提,右側中間區域就是使用在上面提到的方法,得到的這個feature map的前9張響應圖片塊,下方是對這幾張圖片進行反卷積的結果
接下來,我們按‘b'鍵,對這個feature map進行反卷積,
左下方出現的就是特征可視化的結果。
再使用'e’鍵,可以load下一幅圖片,
注意,右側的結果是不會產生變化的,因為那些圖片是提前計算好的。
所以如果我們想使用這個工具可視化自己的CNN的話,我們需要:
1.提前准備好右邊的圖片(將數據集通過CNN,找出Top9張圖片並將其deconv)
2.仿照model文件夾下文件,准備好相應model和配置文件
3.仿照settings_local.py編寫settings_local.template-<your_network>.py
五.總結
通過非參數的可視化方法,我們從一定角度上探索了CNN這個“黑盒”,我們知道了CNN是從底層到高層,從抽象到具體來學習特征的,同時這個可視化也為我們改進網絡結構提供了可能!
References
1. Krizhevsky, A., Sutskever, I., Hinton, G.: Imagenet classification with deep convolutional neural networks. In: NIPS (2012)
2. Girshick, R., Donahue, J., Darrell, T., Malik, J.: Rich feature hierarchies for accurate object detection and semantic segmentation. arXiv:1311.2524 (2014)
3. Y. LeCun, B. Boser, J.S. Denker, D. Henderson, R.E. Howard, W. Hubbard, L.D. Jackel, et al. Hand-written digit recognition with a back-propagation network. In Advances in neural information processing systems, 1990.
4. Zeiler, Matthew D and Fergus, Rob. Visualizing and understanding convolutional neural networks. arXiv preprint arXiv:1311.2901, 2013.
5. J. Yosinski, J. Clune, A. M. Nguyen, T. Fuchs, and H. Lipson, “Understanding neural networks through deep visualization,” CoRR, vol. abs/1506.06579, 2015.
6. Zeiler, M., Taylor, G., Fergus, R.: Adaptive deconvolutional networks for mid and high level feature learning. In: ICCV (2011)
7. Marcher:Concepts and Tricks In CNN
