利用Feature Visualization 了解CNN到底在看什麼

陳宗彥
Taiwan AI Academy
Published in
11 min readMar 24, 2020
GoogLeNet layer4C

看到這些圖片是不是覺得非常的神祕呢?

這些圖片其實是GoogLeNet的layer4C 中的channel做完feature visualization的結果。如果你不知道我在說什麼,沒關係! 這次我就要帶大家來看看Google Brain團隊在 2017年分享的Feature Visualization的成果。

這篇文章是Google Brain團隊在2017年發表在Blog上的文章的導讀,連結在此 https://distill.pub/2017/feature-visualization/

一般我們在談論神經網路時,常常聽到大家說神經網路就是一個黑盒子。你給它一個Input,它吐給你一個Output。而當你想知道它是怎麼運作的? 抱歉,不知道。這個在可解釋性上的缺乏也讓大家對它所做的判斷不敢抱有太多的信心,畢竟在有些領域,理解模型為什麼會下這個判斷是必須的。想像你現在被機器診斷出來患有癌症,但是機器卻沒辦法告訴你它是怎麼判斷的,或是你現在被一家銀行拒絕了貸款申請,但是銀行卻沒辦法告訴你拒絕的理由。不管是哪種情況,我相信所有人都會覺得莫名其妙。所以在致力於打開神經網路這個黑盒子的領域有一個專門的名詞叫做可解釋性AI(Explainable Artificial Intelligence),又被簡稱為XAI。當然在今天我們沒有要過多的談論關於AI可解釋性的問題,今天我們主要要來談的就是對可解釋性做出一些貢獻的小領域,feature visualization。

Feature Visualization是什麼? 它是針對CNN(卷積神經網路)的一個技巧,可以讓我們以圖像的方式去理解CNN內部到底在看些什麼。

一個簡單的CNN架構圖,有一層又一層的卷積層

這是一張簡單的CNN的架構圖,CNN最核心的架構就是一層又一層的convolution layer(卷積層),而convolution layer的重點就是用一個kernel去對輸入圖片做卷積運算來得到一張輸出圖(也被稱作feature map)。

這是一個標準的convolution layer(卷積層) 許多張feature maps代表有許多kernel

一個kernel對輸入圖片上的一個區域(區域大小視kernel大小而定)做完卷積運算後會輸出一個數字,這個數字就是輸出圖片pixel的值。

這是一個卷積運算,左邊是輸入,中間是kernel(也就是神經元),右邊是輸出

這個輸出(activation)的值越大(可以是正數也可以是負數)代表kernel對這個區域反應越大,也就是說kernel對這個區域很關注,並且把這個關注程度用數字的方式輸出。所以如果我們可以知道kernel對於哪種長相的圖像會產生很大的反應的話,就可以知道這一個kernel在看什麼。而CNN又是由一大堆kernel所組成的,所以藉由了解kernel在看什麼,我們就可以知道CNN在看什麼。

Feature Visualization指的就是我們將那些可以引起CNN kernel最大反應的圖像製作出來。當然kernel有很多,許多kernel可以組成一個layer,許多layer構成一個神經網路。所以我們可以針對不同層的不同kernel,或是針對整層的所有kernel去做Feature Visualization。

那們要如何製作讓kernel產生最大反應的圖片呢? 其實方法很簡單,就和我們訓練神經網路的方法一樣。我們在訓練神經網路時是根據我們的loss去改變網路權重,嘗試使loss越小越好。在製作feature visualization時是固定網路權重,根據你想看的kernel的輸出(activation)去改變輸入圖片的像素,嘗試使輸出(activation)越大越好。

這是一個訓練輸入圖片使神經元輸出最大化的過程

當然,你可以不只對kernel做,你也可以對整個Layer或是某幾個kernel做feature visualization。

對單個neuron(單個kernel對某個區域的輸出),對單個channel(單個kernel對整個區域的輸出),整個layer等等的feature visualization

所以,做完feature visualization後,這些圖片代表什麼意思呢? 我們前面提到過,這些圖片是使神經元產生最大反應的圖片,所以這代表我們的神經元就是在關注這些圖片所擁有的特性。

GoogLeNet Layer3A 一個位置比較淺的layer中二號神經元做feature visualization的結果,可以看到這顆神經元關注的是一種特殊的紋理圖案

這可以幫助我們理解CNN在看圖片時,到底是根據哪些東西來判斷的,並且如果你挑選前面的layer和後面的layer做feature visualization,出現的圖片複雜程度顯然不太一樣。

GoogLeNet Layer5A 一個位置比較深的layer中六號神經元做feature visualization的結果,可以看到這顆神經元關注的是一個高度複雜的圖案

這也代表越淺層的神經元做的事情更多是將不同的紋理擷取出來,而深層的神經元會結合這些簡單的紋理特徵合成產生更高複雜度的特徵,像是狗的臉,兔子的毛髮,貓的臉型等等。

到這邊你已經大致了解Feature Visualization的概念了。Feature Visualization就只是讓我們知道CNN中的某個神經元(也可以是某個channel或是某個layer)對什麼樣子的圖片會最在意。而有了這個技巧,我們就能知道CNN到底在看些什麼,看的東西合理不合理。之後的內容則是Google團隊在做Feature Visualization時遇到的一些問題和討論。

進階內容

其實要製造出像我們上面看到的那些圖片,並沒有我們剛剛講的那麼簡單,只要固定好網路權重然後根據神經元activation調整輸入圖片就好。如果你真的這麼做了,你得到的多半是像下面這樣的結果。

不管你如何微調Learning rate,得到的圖片都有許多噪聲

你會發現你嘗試生成的圖片雖然有出現一些圖案,但是其都含有大量的高頻噪聲。而且這些高頻噪聲看上去實在很像是對抗樣本(有興趣的讀者可以搜尋CNN的對抗樣本)會出現的樣貌。但是會出現對抗樣本的pattern看上去也是非常合理,畢竟製造對抗樣本的方式就是微調輸入圖片來讓網路的輸出改變。

目前這些高頻噪聲的出現原因大家還不是太了解,不過似乎是來自CNN中stride和pooling的動作,這會導致網路的梯度出現高頻特徵。

所以如果我們不對圖片的生成做任何限制,我們最後只會得到對抗樣本。所以我們必須對圖片生成加上一些限制條件來阻止這些高頻噪聲的生成。基本上所有的限制方法都不離三個類別,分別是:

  1. 頻率懲罰( Frequency penalization):通過限制高頻信號的出現來阻止高頻噪聲,但是會導致真正的高頻特徵消失(像是銳利的邊緣)。
  2. 變換強健度( Transformation robustness):藉由對圖片進行一些微小的抖動,旋轉或是放大縮小來限制圖片的生成。這些圖片即使做了這些處理,神經網路依然對這張圖片有很高的反應。
  3. 先驗學習( Learned priors):不是從隨機噪聲開始生成圖片,而是從一張可能從Dataset裡挑出的真實的圖片來開始生成,這種方式可以產生最像實際存在的圖片,不過一開始的圖片要怎麼挑是一個問題。

利用這些技巧可以做出比較沒有高頻噪聲的Feature Visualization。但是這些方法都是針對圖片生成去做限制,而且一個很大的缺點是它會改變最後優化到的目標的位置(改變minimum的位置)。作者提出了用另外一個方式來限制高頻噪聲的產生,叫做"Preconditioning”。這其實可以想像成是你在做steepest descent的時候,用另外一種定義的距離來做梯度下降。但是這並不會改變最終的minimum的位置。用這種新的距離定義來做steepest descent時,就可以大幅度抑制圖片的高頻噪聲。

選用不同的距離定義對圖片的影響

這邊作者給出了三種不同precondition對圖片造成的影響,基本上可以看到在decorrelated space上進行優化(optimize)可以最大的抑制高頻噪聲的產生。這邊作者其實沒有寫得很清楚precondition具體來說要如何實現,大家想詳細瞭解的話可以看一下原文的reference。

在這篇文章中所有的圖片除了有例外說明的,基本上都是利用decorrelated space和一些transformation robustness的技巧來產生的。

多樣性也是生成Feature Visualization時需要注意的一個問題。能夠讓神經元產生強烈反應的圖片並不一定都是同一類,而我們平時用簡單的優化方法產生的圖片可能是多種不同類的特徵的混合。

某個channel同時對貓的特徵,狐狸的特徵和汽車的特徵都有強烈的activation

如果想真正了解某個神經元關注的圖片樣貌,我們可以在生成時加入一些”diversity term”來幫助我們產生多種不同類別的圖片。一個diversity term的形式沒有一定,有些方法會是利用某些比較圖片相似度的懲罰來讓生成圖片時不要產生過於相似的圖片,也有一些方法利用到style transfer的點子來讓生成的圖片有不同風格,一樣,想知道詳細細節的讀者的請看原文的reference。

多樣性幫助我們了解單單只是關注一顆神經元,可能並不足夠。或許多顆神經元的組合才是我們想看到的某個類,我的意思是,或許某些神經元的activation的線性組合加起來後,做出的feature visualization才是包含所有的某個類的特徵。神經元A可能包含貓,狐狸,汽車。神經元B包含貓,狗,人等等。只有這些所有包含貓的特徵的神經元的線性組合的feature visualization才是代表貓的feature visualization。

這其實是很合理的,畢竟我們在訓練神經網路時可沒有規定神經元一號要學什麼特徵,神經元二號又要學什麼特徵。某個類別的特徵被多個神經元學習是非常正常的事情。只不過這告訴我們,單單看某個神經元的feature visualization可能還是不足以幫助我們完全了解CNN。

這次帶大家了解Feature Visualization到底在說什麼,希望你看完也能大致上了解它的概念。當然上面一些比較深入的部分我想大家看不懂也沒有關係(除非你要重現Google Brain的成果XD),不過希望大家可以知道整個最大的重點,Feature Visualization就是把CNN中的神經元(channel或是layer)做可視化,而可視化的方式就是固定網路權重然後去改變輸入圖片讓神經元(channel或是layer)的輸出最大化。

希望大家對CNN可解釋性的領域有更多的了解,我們下次再見囉。

--

--